从一个文件读取字符串,grep第一次出现在另一个文件中

时间:2017-08-31 16:11:38

标签: linux unix awk sed grep

我正在从文件appliance_list.txt中读取一个字符串。

appliances_list.txt包含

fridge
dryer
ironbox
microwave 

我正在阅读的文件是myappliances.txt。内容是

I have a fridge
I have another fridge
I have a refridgerator
I have a microwave
I have ironbox at home
I have another microwave
I have a hairdryer

我正在使用

grep -o -m1 -f appliances_list.txt myappliances.txt

输出

fridge

我想要的输出是,第一次出现每个字符串(完全匹配)

fridge
microwave
ironbox

有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:2)

awk 解决方案:

awk 'NR==FNR{ a[$0]; next }{ 
              gsub(/<\/?[^<>]+>/,"",$0); for(i=1;i<=NF;i++) 
              if ($i in a && !a[$i]){ a[$i]++; print $i; break } 
    }' appliances_list.txt myappliances.txt
  • a[$0]; - 从appliances_list.txt

  • 捕获模式字
  • for(i=1;i<=NF;i++) - 遍历来自myappliances.txt

  • 的行的字段/字词

输出:

fridge
microwave
ironbox

答案 1 :(得分:2)

$ cat tst.awk
NR==FNR { strings[$0]; ++numStrings; next }
{
    for (i=1;i<=NF;i++) {
        if ($i in strings) {
            print $i
            delete strings[$i]
            if (--numStrings == 0) {
                exit
            }
            break
        }
    }
}

$ awk -f tst.awk appliances_list.txt myappliances.txt
fridge
microwave
ironbox

这将是非常有效的,因为它将从字符串列表中删除每个找到的字符串,因为它在每一行上都需要更少的比较,当列表中没有更多的字符串将退出程序,因此它不会浪费时间读取第二个文件的剩余行。

答案 2 :(得分:1)

修改您的代码,如下所示。这将非常有效(考虑到您的文件大小为2GB)

while read -r appliance; do grep -m1 -ow $appliance myappliances.txt;done<appliances_list.txt

-w:用于确切的单词匹配

输出:

fridge
ironbox
microwave

说明:
首先,在您的代码中,-m1导致在找到第一个匹配项后停止匹配,并且它会停止读取导致程序退出的文件。

你需要做的就是遍历file1并对其中的每个单词grep over file2并使用你的逻辑。

其他解决方案是:

使用 head -1 和grep一起找到第一个匹配后停止搜索。

while read -r appliance; do grep -ow $appliance myappliances.txt | head -1; done<appliances_list.txt

答案 3 :(得分:0)

删除-m1并管道到sort -u

grep -owf appliances_list.txt myappliances.txt | sort -u

sort -u将排序然后将这些行唯一。如果不希望进行排序,则可能必须使用awk之类的东西。 perl,或python。

请注意,要仅获取dryer而不是hairdryer,您需要grep -w,因此上面的建议包含-o w