如何使用 awk 计算多个文件中不以 # 开头的行并用文件名列出它们?

use*_*385 3 grep awk text-processing

我一直用来grep "^[^#]" file.txt | wc -l计算单个文件中的行数。

如何计算awk不以以下内容开头的行数#并打印出如下文件名?

file1.txt 30 
file2.txt 33
....
Run Code Online (Sandbox Code Playgroud)

Ste*_*itt 6

您还可以通过以下方式执行此操作grep:

\n
grep -c "^[^#]" *\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
grep -cv "^#" *\n
Run Code Online (Sandbox Code Playgroud)\n

前者还排除空行;后者没有\xe2\x80\x99t。

\n

请注意,如果当前目录中存在单个文件,则 \xe2\x80\x99 不会显示文件名;您可以通过添加选项来避免某些版本grep(包括 GNU grep)的这种情况-H:

\n
grep -cvH "^#" *\n
Run Code Online (Sandbox Code Playgroud)\n

GNUgrep还支持递归搜索以下降目录树:

\n
grep -rcvH "^#" .\n
Run Code Online (Sandbox Code Playgroud)\n

输出与您所要求的\xe2\x80\x99不太匹配,它最终会像

\n
file1.txt:30\nfile2.txt:33\n
Run Code Online (Sandbox Code Playgroud)\n

但这可以通过通过管道输出来解决sed 's/:\\([^:]*\\)$/ \\1/'。

\n


αғs*_*нιη 5

这是你可以做的awk(同样^[^#]适用grep于 awk ,但在awk正则表达式匹配中写在斜杠对内/.../(也有其他方法)):

find . -type f -exec \
    awk '/^[^#]/ {count++}; END{ print FILENAME, count+0 }' {} \;
Run Code Online (Sandbox Code Playgroud)

或者如果你有一个用于该ENDFILE{}块的 GNU awk:

gawk '/^[^#]/{ count++ }; ENDFILE{ print FILENAME, count+0; count=0 }' ./multiple.files*
Run Code Online (Sandbox Code Playgroud)

或者递归地:

find . -type f -exec \
    gawk '/^[^#]/{ count++ }; ENDFILE{ print FILENAME, count+0; count=0 }' {} +
Run Code Online (Sandbox Code Playgroud)
笔记:
  • 使用/^[^#]/将跳过空行计数。_
  • 仅当输入中没有空行时,使用!/^#/才相当于有条件的,否则也会对空行进行计数,这就是它的真正作用,并且在询问“计算不以 # 开头的行”时更正确/^[^#]/!/^#/
  • !/^#/与的完全相同/^([^#]|$)/(因此两者也会计算空行)

考虑到上述几点,如果您也想计算空行,如“计算不以 # 开头的行”,请执行以下操作:

awk '!/^#/{count++} END{ print FILENAME, count+0 }'
Run Code Online (Sandbox Code Playgroud)

或其同等:

awk '/^([^#]|$)/{count++} END{ print FILENAME, count+0 }'
Run Code Online (Sandbox Code Playgroud)

或者(由@EdMorton建议):

awk '/^#/{ count++ } END{ print FILENAME, FNR-count }'
Run Code Online (Sandbox Code Playgroud)

并对 GNU awk 形式应用相同的方法:

awk '/^#/{ count++ } ENDFILE{ print FILENAME, FNR-count; count=0 }'
Run Code Online (Sandbox Code Playgroud)

如果您想在文件充满注释行时跳过打印输出:

awk '/^#/{ count++ } END{ if(count) print FILENAME, FNR-count }'
Run Code Online (Sandbox Code Playgroud)