grep:将每行中一个或多个单词的列表与文本文件进行比较

时间:2011-01-14 08:03:21

标签: list comparison grep

我正在使用Debian / GNU Linux操作系统,喜欢使用简短的shell命令(终端或外部脚本)。

我的目标:我在foo.txt中有一个单词列表,如

---- foo.txt ----

dog
cat
mouse with hat

---- /foo.txt ----

并希望将此列表与bar.txt进行比较(将正常文本与某些段落相比较)。

我想要两种匹配:

  1. 每行的所有单词都应该匹配(例如'带帽子的鼠标'以及'帽子')

  2. 只有每一行的第一个外观应该匹配

  3. 与第一个问题相关:

    我的第一个代码(到目前为止命令行)和我的问题:

    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
    

    在第一场比赛结束后停止。但我喜欢“搜索任何第一场比赛并在浏览整个列表后停止”。

1 个答案:

答案 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)