[英]Shell script Sed - How to read a file and write in another file only in the first occurrence of a string?
[英]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.