[英]Linux commands to find two comparable rows
我具有以下排序順序的數據(此處是按照第一個v1,v2,v3和v4排序的數據):
v1=1 v2=8513481 v3=119330184 v4=0
v1=1 v2=8521383 v3=119330182 v4=0
v1=1 v2=10630231 v3=60529116 v4=18
v1=1 v2=60528877 v3=60529221 v4=17
v1=1 v2=90351079 v3=90351078 v4=20
v1=1 v2=271669588 v3=271669683 v4=101
v1=2 v2=8513481 v3=10583646 v4=0
v1=2 v2=10175437 v3=10175436 v4=0
v1=2 v2=10630231 v3=60528947 v4=17
v1=2 v2=10630231 v3=60529119 v4=18
v1=2 v2=10630232 v3=605291191 v4=18
現在,我想找出兩行的v1和v2相等的行。 即在上面給出的數據中,我想找到以下形式的行:
v1=2 v2=10630231 v3=60528947 v4=17
v1=2 v2=10630231 v3=60529119 v4=18
我知道如何在python中通過比較連續的行以及何時有匹配項輸出行來做到這一點。 有沒有一種簡單的方法可以使用sed等linux命令執行相同的操作。我知道當給定兩個值時如何使用sed查找單詞,但是在這種情況下我不知道如何使用sed。 高度贊賞的解釋。
使用awk
會更容易一些:
awk '{
lines[$1,$2]=(lines[$1,$2]?lines[$1,$2] RS $0:$0)
dups[$1,$2]++
}
END {
for(line in lines)
if(dups[line]>1) print lines[line]
}' file
v1=2 v2=10630231 v3=60528947 v4=17
v1=2 v2=10630231 v3=60529119 v4=18
lines
和dups
。 dups
數組。 lines
數組中,我們檢查是否存儲了第一列和第二列相同的行。 如果有,我們將重復的行添加到它。 END
塊中,我們遍歷lines
數組。 如果在dups
數組中多次發現first和column,我們將打印這些行。 另外,如果您不想將整個文件保留在內存中,則可以執行以下操作(因為您聲明數據已經排序):
awk '($1==c1 && $2==c2){print line RS $0}{line=$0;c1=$1;c2=$2}' file
line
分配為您的整個當前行,將c1
分配為第1列,將c2
分配為第2列。 首先,讓我開始說,您顯示的列表不是嚴格意義上的Linux排序(空格和制表符確實會影響排序)。 針對您的問題的最佳Linux解決方案是使用awk。 這是應該執行您要尋找的命令:
awk -e '{cur=$1 " " $2; if (NR>1 && cur==prev) {print "line:"NR " " cur} prev=cur}' < input_file
所有這些操作就是比較由輸入文件的第一和第二列($ 1和$ 2;用空格隔開的空格,用於更清潔的輸出)的組合所形成的字符串,我們將其稱為cur ,並將其與前一個輸入行的字符串相同上一個 如果兩個字符串匹配,則輸出行號和結果。 我們還添加了一個條件以跳過文件的第一行,因為尚無可比較的內容。
這可能對您有用(GNU sed):
sed -rn '$!N;/^\s*(\S+)\s+(\S+)\s+.*\n\s*\1\s+\2/p;D' file
這使用反向引用比較兩行,並打印出與前兩個值重復的那些行。
但是,如果重復項可能是三行或更多行,則可以使用另一種方法。 使用保留緩沖區打印並標記重復項。 當遇到重復項,接着是非重復行時,還會打印最后一條重復行,並重置標志:
sed -rn '$!N;/^\s*(\S+)\s+(\S+)\s+.*\n\s*\1\s+\2/{h;P;D};x;/./{z;x;P;D};x;D' file
一種方法是找出行首有多少個相同字符(看起來大約25個?),然后僅通過uniq
比較多個字符:
uniq --check-chars=25 --repeated < input_file
要打印兩行,請使用--all-repeated
而不是--repeated
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.