簡體   English   中英

從一個文件中讀取字符串,grep在另一個文件中的第一個匹配項

[英]Read string from one file, grep the first occurrence in another file

我正在從文件devices_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

有人可以指出我正確的方向嗎?

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
$ 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

這將非常有效,因為它會從找到的字符串列表中刪除找到的每個字符串,因此每一行的比較需要的次數更少,並且當列表中沒有更多的字符串時,退出程序,這樣就不會浪費時間閱讀第二個文件的其余行。

如下修改您的代碼。 這將非常有效(考慮您的文件大小為2GB)

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

-w :完全匹配單詞

輸出:

fridge
ironbox
microwave

說明:
首先,在您的代碼中,一旦找到第一個匹配項, -m1將導致停止匹配,並且它將停止讀取文件,從而導致程序退出。

您要做的是遍歷file1,並針對其中的每個單詞grep遍歷file2並使用您的邏輯。

其他解決方案是:

找到第一個匹配項后,將head -1與grep一起使用可停止搜索。

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

刪除-m1並用管道sort -u進行sort -u

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

sort -u將對行進行排序,然后對其進行唯一化。 如果不希望這種排序,則可能必須使用awk之類的東西。 perl或python。

請注意,僅dryer而不是hairdryer您需要grep -w ,因此上述建議具有-o w

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM