awk - 使用管道和字数(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
在命令替换中。
但是,您可以使用(或 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
-w
grep
推荐阅读
- javascript - JavaScript - 自定义 Google 登录必须点击两次
- c++ - { } 和等号变量之间的区别
- regex - 将所有正则表达式匹配捕获到一个向量中
- c# - LINQ - 使用 SUM IF 分组
- javascript - 使用 ajax 发送带有嵌套在列表中的文件的 json
- python - 有没有更好的方法在线程中运行 uvicorn?
- azure-lab-services - 用于 ALS 的电子邮件地址是什么?
- c - pthread_mutex_t 在结构中并在访问时锁定结构
- pyspark - 数据帧列中动态长度的 Pyspark 字符串数组到 onehot 编码
- javascript - 我想默认设置当前日期和时间并显示在输入字段中