递归计算目录中所有文件的列中具有特定值的行数

递归计算目录中所有文件的列中具有特定值的行数

我的目录中有 40 个文件,我想分别计算每个文件的第一列中包含“2”的行的次数。

我正在尝试这样的事情,但它打印出每个文件的总和,我想要单独的总和:

find . -type f -print0 | xargs -0 awk '($1=="2"){++count} END {print count}'

只是为了清楚起见,这是一个示例:

文件_1

2   345     123     4
2   4567    2344    6
3   2345    657     87
6   234     345     6

文件_2

1   12  436 7
2   54  86  8
2   23  48  0
2   098 0   8
8   98  9   0

打印:

FILE_1 2
FILE_2 3

我实际得到的是:

打印:

5 

感谢您的帮助!

答案1

你可以grep帮你数一下。假设您需要的行以 开头2,您可以使用以下内容:

grep -c '^[[:space:]]*2\>' $(find . -type f -print0 | xargs -0 echo)

正则\>表达式末尾的 可以确保匹配将在“字边界”处停止,以避免误报,例如以 20 而不是 2 开头的行。

笔记:

如果您要查找的“40 个文件”都在同一目录中(而不是在子目录中),则可以find仅搜索当前目录而不递归(以便减少延迟),如下所示:

find -maxdepth 1 . -type f -print0

更新:

要匹配 2 出现在与第一列不同的列中的文件,您可以执行以下操作:

COLNUM=3
TOMATCH=$(($COLNUM-1))
grep -cE "^[[:space:]]*([0-9]+[[:space:]]+){$TOMATCH}2\>" \
$(find . -type f -print0 | xargs -0 echo)

您可以COLNUM根据需要进行更改。基本上,它的作用是尝试匹配COLNUM-1单词边界处后跟 2 的列。-E需要使用该开关来启用扩展正则表达式,它允许您使用{}符号来指定数字量词(即“与先前的模式匹配多次”)。

但请注意,如果您输入文件中不存在的列号,则正则表达式将默默失败。

答案2

几个解决方案:

  1. awk使用选项在每个文件上执行find -exec

    find . -type f \
    -exec awk '($1=="2"){++count}END{print FILENAME ": " count}' {} \;
    
  2. 使用 awkFNR变量来检测 awk 脚本中的文件更改:

    find . -type f -print0 | xargs -0 \
    awk 'FNR==1{if (NR!=1){print count} printf("%s: ", FILENAME);}($1=="2"){++count}END{print count}'
    

答案3

如果您不介意更改输出,可以执行以下操作:

$ grep "^2" *|awk '{print $1}'|uniq -c
      2 FILE_1:2
      3 FILE_2:2

如果您想要打印输出:

$ grep "^2" *|awk '{print $1}'|uniq -c|sed 's/:2//'|awk '{print $2, $1}'
FILE_1 2
FILE_2 3

相关内容