簡體   English   中英

Linux命令查找兩個可比較的行

[英]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
  • 我們創建兩個數組。 linesdups
  • 當第一列和第二列被多次查看時,我們將增加計數。 我們為此使用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列。
  • 如果當前行的第1列和第2列與上一列和第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.

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