![grep -v 问题获取超过一千个文件的行数(单个行数)](https://linux22.com/image/208237/grep%20-v%20%E9%97%AE%E9%A2%98%E8%8E%B7%E5%8F%96%E8%B6%85%E8%BF%87%E4%B8%80%E5%8D%83%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E8%A1%8C%E6%95%B0%EF%BC%88%E5%8D%95%E4%B8%AA%E8%A1%8C%E6%95%B0%EF%BC%89.png)
我需要在 VCF 文件上使用此命令:
grep -v "#" {name of VCF file} | wc -l
这给了我没有“#”的行数。
但我的问题是,我的目录中有很多文件,我需要单独的行计数。所以我需要每个文件中不带“#”的行数。
当我这样做时:grep -v "#" *.vcf* | wc -l
,管道只是总结所有文件的行,不带 #。我需要分别了解每个文件的行数。我无法手动通过管道传输每个文件的行(我有一千多个文件)。任何人都可以建议我如何获取每个文件的行数。先感谢您!
答案1
只需使用grep -c
而不是管道wc -l
:
grep -c -v -- '#' *.vcf
请注意,如果当前目录中只有一个 vcf 文件,则不会输出其名称,您只会得到计数。
grep
要解决这个问题,您可以通过 GNU 实现或兼容来添加该-H
选项。
grep -Hcv -- '#' *.vcf
对于其他实现,您可以随时将其添加/dev/null
到列表中并通过管道tail -n +2
将其删除:
grep -c -v -- '#' /dev/null *.vcf | tail -n +2
(尽管除非您设置支持的 shell 选项,否则您将grep
在此过程中丢失退出状态)。pipefail
另一方面,如果您只需要不带文件名的每个计数,请使用-h
而不是-H
GNU ,或者使用不支持的实现的grep
循环:grep
-h
for file in *.vcf; do grep -cv '#' < "$file"; done
或者报告整体退出状态的失败:
(
ret=0
for file in *.vcf; do
grep -cv '#' < "$file" || ret=$?
done
exit "$ret"
)
如果你得到一个参数列表太长grep
错误,您可以借助以下工具将列表拆分为多个调用xargs
(此处假设为 GNU 工具):
printf '%s\0' *.vcf | xargs -r0 grep -cvH -- '#'
或者如果zsh
与它一起使用zargs
:
autoload zargs
zargs -r -- *.vcf(Nn.) -- grep -cvH -- '#'
(这里还使用其 glob 限定符功能来限制为常规文件 ( .
),对文件列表使用数字排序顺序 ( n
) 并避免在没有 vcf 文件 ( -r
with N
) 时出现错误)。