我正在使用Debian / GNU Linux操作系统,喜欢使用简短的shell命令(终端或外部脚本)。
我的目标:我在foo.txt中有一个单词列表,如
---- foo.txt ----
dog
cat
mouse with hat
---- /foo.txt ----
并希望将此列表与bar.txt进行比较(将正常文本与某些段落相比较)。
我想要两种匹配:
每行的所有单词都应该匹配(例如'带帽子的鼠标'以及'帽子')
只有每一行的第一个外观应该匹配
与第一个问题相关:
我的第一个代码(到目前为止命令行)和我的问题:
for i in foo.txt; do fgrep -f foo.txt bar.txt
只匹配列表的第一个单词。 现在我想我必须使用像
这样的东西for i in foo.txt; do fgrep -e <some-kind-of-regexp> -f foo.txt bar.txt
但我陷入了正则表达式:(
与第二个问题相关 为了停止grep,我只知道-m选项。
for i in foo.txt; do fgrep -m 1 -f foo.txt bar.txt
在第一场比赛结束后停止。但我喜欢“搜索任何第一场比赛并在浏览整个列表后停止”。
答案 0 :(得分:1)
对于您的第一个问题,您需要在将列表分配给单个单词之前将其分配给grep。我使用awk,但你也可以使用sed。我正在分裂空白,但你可以很容易地分解非字母数字,如果这是你想要的:
fgrep -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt
对于你的第二个问题,你需要有点花哨。首先,输出行号以及每个匹配的字符串,然后您可以在匹配的字符串上唯一,以获取与每个字符串匹配的行号。
cat bar.txt \
| mawk '{print NR,$0}' \
| join -1 1 -2 1 - <(fgrep -o -n -f <(mawk 'BEGIN{FS=" "}{print; if(NF > 1)for(i=1; i<=NF; i++)print $i}' foo.txt) bar.txt \
| sort -k2,2 -k1,1n \
| sort -k2,2 -us \
| cut -f1 \
| sort -k1,1)