使用管道和字数wc然后整理结果

问题描述

我想打扮我正在做的grep的输出

想象一下一个包含大量文本的文件text.txt。然后我执行命令:

grep fred text.txt | wc -l
grep bob text.txt | wc -l
grep james text.txt | wc -l

我得到输出

12
3
4

我要在输出显示内容是:

fred was found on 12 lines.
bob was found on 3 lines.
james was found on 4 lines.

我该怎么做?

解决方法

在shell脚本中,使用grep -c对行进行计数:

for name in fred bob james
do
    echo "$name was found on $(grep -c $name text.txt) lines."
done

这将运行一半的进程。假设您最终不想使用空格('lucy anne')或引号("o'reilly")来搜索名称-如果您需要更通用的名称,还可以在命令替换中,在$name周围使用双引号需要更加小心。

但是,您可以使用awk(或Perl或Python或…)扫描一次文件,如果文件很大,则可以节省很多:

awk '
    /fred/  { count["fred"]++ }
    /bob/   { count["bob"]++ }
    /james/ { count["james"]++ }
   END      { for (name in count) print name,"was found on",count[name],"lines." }
   ' text.txt

这与answerRavinderSingh13类似,但它仅计算出现名称的行,而不统计出现的总数(因此,如果一行包含“鲍勃在水面上晃动,所有散乱的气泡” ,它将计为1行,而不是3次)。请注意,搜索既不区分大小写(不计入“ Bob”),也不受任何合理的单词定义约束来匹配“单词”。这些注释也适用于grep解决方案,但是您也可以使用诸如-i这样的选项来区分大小写(来自POSIX),而使用-w来匹配单词(GNU grep以及其他一些,例如BSD以及macOS X)。

,

您可以尝试在awk中进行跟踪(由于未提供示例,因此未进行测试),以防您awk没事,无需运行许多grep + {{1} }命令,可以在单个wc程序本身中完成。

awk