簡體   English   中英

同時打印匹配和非匹配模式

[英]Printing Both Matching and Non-Matching Patterns

我正在嘗試比較兩個文件,然后在匹配時返回文件列之一。 我現在使用的代碼不包括非匹配模式,而只是打印出匹配模式。 我需要使用grep打印所有匹配和不匹配的結果。

文件1:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2

檔案2:

F
A
B
Z
C
P
E

當前結果:

A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2

預期結果:

F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E

重擊代碼:

while IFS=',' read point lat lon; do

check=`grep "${point} /home/aaron/file2 | awk '{print $1}'`

echo "${check},${lat},${lon}"

done < /home/aaron/file1

在awk中:

$ awk -F, 'NR==FNR{a[$1]=$0;next}{print ($1 in a?a[$1]:$1)}' file1 file2
F
A,42.4,-72.2
B,47.2,-75.9
Z,38.3,-70.7
C,41.7,-95.2
P
E

解釋:

$ awk -F, '                  # field separator to ,
NR==FNR {                    # file1
    a[$1]=$0                 # hash record to a, use field 1 as key
    next
}
{
    print ($1 in a?a[$1]:$1) # print match if found, else nonmatch
}
' file1 file2

如果您不關心順序,那么GNU coreutils中有一個join二進制文件可以滿足您的需要:

$sort file1 > sortedFile1
$sort file2 > sortedFile2
$join -t, -a 2 sortedFile1 sortedFile2
A,42.4,-72.2
B,47.2,-75.9
C,41.7,-95.2
E
F
P
Z,38.3,-70.7

它依賴於要排序的文件,否則將無法正常工作。

現在,請您離開我的/home/嗎?

另一個基於join的解決方案,保留訂單

f() { nl -nln -s, -w1 "$1" | sort -t, -k2; }; join -t, -j2 -a2 <(f file1) <(f file2) | 
sort -t, -k2 | 
cut -d, -f2 --complement

F
A,42.4,-72.2,2
B,47.2,-75.9,3
Z,38.3,-70.7,4
C,41.7,-95.2,5
P
E

無法擊敗awk解決方案,而是使用基於decorate-unecorate模式的unix工具鏈的另一種選擇。

您當前解決方案的問題:
1 您缺少grep "${point} /home/aaron/file2的雙引號。
2 您應該從另一個文件開始以打印該文件中的所有行

while IFS=',' read point; do
   echo "${point}$(grep "${point}" /home/aaron/file1 | sed 's/[^,]*,/,/')"
done < /home/aaron/file2

3 grep可以給出多個結果。 您想要哪一個( head -1 )?
一個改進將是

while IFS=',' read point; do
   echo "${point}$(grep "^${point}," /home/aaron/file1 | sed -n '1s/[^,]*,/,/p')"
done < /home/aaron/file2

4 使用while是錯誤的方法。
對於較小的文件,它可以完成工作,但是您將被較大的文件所困擾。 原因是您將為file2中的每一行調用grep ,並多次讀取file1。
更好的方法是使用awk或其他解決方案。 另一個解決方案是將sed與另一個sed命令的輸出結合使用:

sed -r 's#([^,]*),(.*)#s/^\1$/\1,\2/#' /home/aaron/file1

這將為第二個sed提供命令。

sed -f <(sed -r 's#([^,]*),(.*)#s/^\1$/\1,\2/#' /home/aaron/file1) /home/aaron/file2

暫無
暫無

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

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