我有以下排序顺序的数据(这里数据按照第一个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。我们非常感谢您的一些解释。
答案 0 :(得分:3)
使用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
数组中多次找到第一列和第一列,我们会打印这些行。 或者,如果您不想将整个文件保留在内存中,则可以执行以下操作(因为您声明您的数据已经排序):
awk '($1==c1 && $2==c2){print line RS $0}{line=$0;c1=$1;c2=$2}' file
line
指定为整个当前行,c1
指定为第1列,将c2
指定为第2列。答案 1 :(得分:1)
首先让我首先说明你所显示的列表并没有严格按照Linux意义排序(空格和制表符会影响排序)。针对您的问题,最好的Linux解决方案是使用awk。这是一个应该做你想要的命令:
awk -e '{cur=$1 " " $2; if (NR>1 && cur==prev) {print "line:"NR " " cur} prev=cur}' < input_file
所有这一切都是比较由输入文件的第一列和第二列的组合形成的字符串($ 1和$ 2;用更清洁输出的空格分隔),我们称之为 cur 来自上一个输入行的相同字符串,我们称之为 prev 。如果两个字符串匹配,我们输出行号和结果。我们还添加了一个条件来跳过文件的第一行,因为还没有什么可比较的。
答案 2 :(得分:1)
这可能适合你(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
答案 3 :(得分:0)
一种方法是找出行开头有多少个字符相同(看起来大约是25?),只通过uniq
比较那么多字符:
uniq --check-chars=25 --repeated < input_file
要打印这两行,请使用--all-repeated
代替--repeated
。