Linux命令来查找两个可比较的行

我有以下sorting顺序的数据(这里的数据按照第一个v1,然后是v2,然后是v3,然后是v4)sorting:

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是相等的行。 即在上面给出的数据中,我想查找以下forms的行:

  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数组中找到第一个和第一个列,我们打印这些行。

或者,如果您不想将整个文件保存在内存中,则可以执行以下操作(因为您声明数据已经排序):

 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