我想找到一个单词在文本文件中出现的位置 - 就像单词出现在文本中的单词数量一样 - 对于该单词的所有实例,但我什至不知道从哪里开始。我想我需要一个循环,以及 grep 和 wc 的某种组合。
举个例子,这里有一篇关于 iPhone 11 的文章:
周二,该公司表示,其入门级手机 iPhone 11 起售价为 700 美元,而去年同类机型的起售价为 750 美元,这表明苹果公司正在关注那些不会竞相购买更昂贵手机的消费者。年。
苹果将其更先进型号 iPhone 11 Pro 和 iPhone 11 Pro Max 的起价保持在 1,000 美元和 1,100 美元。该公司在硅谷园区举行的 90 分钟新闻发布会上推出了新款手机。
正文共有81字。
jaireaux@macbook:~$ wc -w temp.txt
81 temp.txt
“iPhone”这个词出现了三次。
jaireaux@macbook:~$ grep -o -i iphone temp.txt | wc -w
3
我想要的输出是这样的:
jaireaux@macbook:~$ whereword iPhone temp.txt
24
54
57
我该怎么做才能获得该输出?
答案1
这是一种方法,使用 GNU 工具:
$ tr ' ' '\n' < file | tr -d '[:punct:]' | grep . | grep -nFx iPhone
25:iPhone
54:iPhone
58:iPhone
第一个用tr
换行符替换所有空格,然后第二个删除所有标点符号(以便iPhone,
可以作为单词找到)。确保grep .
我们跳过任何空行(我们不想计算这些空行)并将grep -n
行号附加到输出中。然后,-F
告诉grep
不要将其输入视为正则表达式,并且它-x
应该只查找跨越整行的匹配项(因此job
不会算作 的匹配项jobs
)。请注意,您在问题中给出的数字少了一位。
如果您只想要数字,您可以添加另一个步骤:
$ tr ' ' '\n' < file | tr -d '[:punct:]' | grep . | grep -nFx iPhone | cut -d: -f1
25
54
58
正如评论中所指出的,这仍然会存在诸如aren't
或 之类的“单词”问题double-barreled
。您可以使用以下方法进行改进:
tr '[[:space:][:punct:]]' '\n' < file | grep . | grep -nFx iPhone
答案2
使用 tr 命令将所有空格替换为单个换行符(使用挤压选项)。
通过管道将其传递给 nl -ba,它按顺序对每行(以及单词)进行编号。
通过管道将其发送到 grep -F 以获取您想要的单词。这将仅显示这些单词的编号和文本。
awk 也会在一个过程中完成此操作,但可能看起来更复杂。
答案3
另一种选择是sed
:
sed -e '/^$/d' -e 's/^[[:blank:]]*//g' < file | sed 's/[[:blank:]]/\n/g' | grep -ion "iphone"
输出:
25:iPhone
54:iPhone
58:iPhone
答案4
创建一个函数。
$ whereword(){ grep -ion "$1" -<<<$(egrep -o "[^[:blank:]]+" "$2"); }
$ whereword iPhone tmp.txt
25:iPhone
54:iPhone
58:iPhone
$ whereword "aren't" tmp.txt
14:aren't