6

我一直在努力使我编写的脚本更简单。

有很多方法可以获取文件夹中所有文件的字数,甚至是文件夹子目录的所有文件。

例如,我可以写

wc */* 

我可能会得到这样的输出(这是所需的输出):

   0        0        0 10.53400000/YRI.GS000018623.NONSENSE.vcf
   0        0        0 10.53400000/YRI.GS000018623.NONSTOP.vcf
   0        0        0 10.53400000/YRI.GS000018623.PFAM.vcf
   0        0        0 10.53400000/YRI.GS000018623.SPAN.vcf
   0        0        0 10.53400000/YRI.GS000018623.SVLEN.vcf
   2       20      624 10.53400000/YRI.GS000018623.SVTYPE.vcf
   2       20      676 10.53400000/YRI.GS000018623.SYNONYMOUS.vcf
  13      130     4435 10.53400000/YRI.GS000018623.TSS-UPSTREAM.vcf
 425     4250   126381 10.53400000/YRI.GS000018623.UNKNOWN-INC.vcf

但如果文件太多,我可能会收到如下错误消息:

-bash: /usr/bin/wc: Argument list too long

因此,我可以创建一个变量并一次执行一个文件夹,如下所示:

while read $FOLDER
do
    wc $FOLDER/* >> outfile.txt
done < "$FOLDER_LIST"

所以这从一行到 5 就像那样。

此外,在一种情况下,我想先使用grep -v,然后进行字数统计,如下所示:

grep -v dbsnp */* | wc

但这会受到两个错误的影响:

  1. 参数列表太长
  2. 如果它不是太长,它将一次为所有文件提供 wc ,而不是每个文件。

所以,回顾一下,我希望能够做到这一点:

grep -v dbsnp */* wc > Outfile.txt
awk '{print $4,$1} Outfile.txt > Outfile.summary.txt

并让它像我上面显示的那样返回输出。

有没有一种非常简单的方法可以做到这一点?或者我至少在看一个循环?再一次,我知道 101 种方法来做到这一点,就像我们其他人使用 4-10 行脚本一样,但我希望能够在命令提示符中输入 2 个单行...而且我对 shell 的了解是还不够深入,无法知道哪些方式可以允许我对操作系统的要求。

编辑 -

提出了一个解决方案:

find -exec grep -v dbsnp {} \; | xargs -n 1 wc

此解决方案导致以下输出:

wc: 1|0:53458644:AMBIGUOUS:CCAGGGC|-16&GCCAGGGCCAGGGC|-18&GCCAGGGCC|-19&GGCCAGGGC|-19&GCCAGGGCG|-19,.:48:48,48:4,4:0,17:-48,0,-48:0,0,-17:27:3,24:24: No such file or directory
wc: 10: No such file or directory
wc: 53460829: No such file or directory
wc: .: Is a directory
      0       0       0 .
wc: AA: No such file or directory
wc: CT: No such file or directory
wc: .: Is a directory
      0       0       0 .
wc: .: Is a directory
      0       0       0 .

据我所知,似乎将每一行视为一个文件。我仍在审查其他答案,感谢您的帮助。

4

4 回答 4

3

您提到“这并不能解决逐项退回厕所的问题”

以下将:

find -exec wc {} \;

但这不会随您的grep过滤器一起提供"grep -v"

如果您打算按照我对此答案的评论所指示的那样做,那么请检查以下内容是否适合您:

find -exec bash -c  "echo -n {}; grep -v dbsnp {} | wc " \;
于 2014-06-05T07:24:01.780 回答
2

你有太多的匹配项,*/*所以 grep 会收到一个很长的参数列表。你可以使用find来规避这个:

find -exec grep -v dbsnp {} \; | wc

也许您也想摆脱可能的遍历错误:

find -exec grep -v dbsnp {} \; 2> /dev/null | wc
于 2014-06-05T06:20:12.333 回答
0

这对我有用:

grep -or "[a-zA-Z]*" * | cut -d":" -f2 | sort | uniq -c

您正在寻找的是 MapReduce 算法http://en.wikipedia.org/wiki/MapReduce

于 2014-06-05T06:39:43.930 回答
0

根据 perreal 的回答:

如果你想要一个wc文件一个文件,你可以使用xargs

find -exec grep -v dbsnp {} \; | xargs -n 1 wc

xargs可以读取标准输入并使用它构建和执行命令行。因此,它会读取输入流的结果并wc针对每个项目 ( -n 1) 执行。

于 2014-06-05T06:55:12.867 回答