首页 > 解决方案 > 使用管道和字数(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.

我怎样才能做到这一点?

标签: awkgrepwc

解决方案


在 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在命令替换中。

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

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

这类似于RavinderSingh13的答案,但它只计算名称出现的行,而不是出现的总数(因此,如果一行包含“bob was bobbing on the water all discombobated”,它将计算 1 行,而不是 3 次出现) . 请注意,搜索既不区分大小写(“Bob”不会被计算在内),也不会被限制为匹配“单词”以获得任何合理的单词定义。这些注释也适用于解决方案,但您也可以使用诸如不区分大小写(来自 POSIX)和匹配单词(GNU和其他一些,例如 BSD 和因此 macOS X)之类的选项。grep-i-wgrep


推荐阅读