Bash 按扩展和路径模式计数代码行

Bash 按扩展和路径模式计数代码行,bash,shell,grep,find,Bash,Shell,Grep,Find,我有一个bash查询,可以帮助我计算代码行数: find。“(“-name”*.ext”“)”-print0 | xargs-0 wc-l 我还想用某种模式计算特定目录中的代码行(例如,所有以“@”符号开头的th目录)。然而,-name参数似乎只检查文件名,而不是全名或路径 因此,我想我可以使用grep过滤输出,其中包含完整路径: find。“(“-name”*.ext”“)”-print0|grep”/@“| xargs-0 wc-l 但grep无法处理: 二进制文件(标准输入)匹配 我还

我有一个bash查询,可以帮助我计算代码行数:

find。“(“-name”*.ext”“)”-print0 | xargs-0 wc-l
我还想用某种模式计算特定目录中的代码行(例如,所有以“@”符号开头的th目录)。然而,
-name
参数似乎只检查文件名,而不是全名或路径

因此,我想我可以使用
grep
过滤输出,其中包含完整路径:

find。“(“-name”*.ext”“)”-print0|grep”/@“| xargs-0 wc-l
但grep无法处理:

二进制文件(标准输入)匹配

我还试图从
find
中删除
-print0
,并将
-a
添加到
grep

find。(“-name”*.ext”“)“|grep-a”/@”xargs-0 wc-l
通过这种方式,我可以按路径过滤文件列表,但这也会导致
xargs
出现问题:

打开:文件名太长


我怎样才能达到预期的结果?另外,非常欢迎解释它是如何工作的以及上次查询失败的原因。

手册页中的
-print0
选项:

-打印0 是的;在标准输出上打印完整文件名,后跟空字符(而不是 -打印使用)

您在单行输出上使用了
grep
。 此外,如果使用path
运行,则此选项不会打印完整路径

因此,我建议:


find。“(“-name”*.ext”“)”-exec readlink-f{}\|grep“@”| xargs wc-l

您的逻辑似乎是正确的,但命令的用法不太正确。当你找到时。“(“-name”*.ext”“)”-print0|grep”/@“您正在传递来自
find
命令的全部搜索结果,这些结果以NULL分隔,作为要搜索
grep
的内容,但它不喜欢所看到的数据类型

通常
grep
通过查看文件输入流的前几个字节(从文件或通过stdin)来确定文件是否为二进制文件。由于您使用空分隔符传递来自
find
的结果,因此无法将其标识为文本输入,并将其视为二进制数据,并在相同的数据上抛出错误

以后,你用<代码> -a < /COD>标志将给定的二进制数据作为文本数据考虑,现在搜索整个空分隔的结果为>/@ ,但是显示的搜索结果不是与你的模式匹配的唯一结果,但仍然是来自<代码>的全部原始结果找到命令。您可以做的变通方法是,通过添加
-z
标志,让大家知道
grep
以空终止结果

find . -name "*.ext" -print0 | grep -az "/@" | xargs -0 wc -l
或者,您可以使用
find
本身中支持的正则表达式选项。假设您想在以
@
开头的目录中搜索带有
.ext
的文件,您可以这样做

find . -type f -regex ".*[@].*/.*ext" -print0 | xargs -0 wc -l

谢谢您的方法工作正常,但似乎更快。感谢您的详细解释!