Awk 比较并打印文件中的最后一列

Awk 比较并打印文件中的最后一列,awk,sed,Awk,Sed,我有一份档案 (n34)); 1 Z(n2)); 1 (n52)); 2 (n35)); 3 (n67)); 3 (n19)); 4 (n68)); 4 (n20)); 5 (n36)); 5 (n53)); 5 (n69)); 5 N(n3)); 5 (n54)); 6 (n70)); 7 N(n4)); 7 我希望输出的结果是,只要分号后面有相同的数字,就用字段分隔符打印单行 输出应该是 (n34)); 1;Z(n2)); 1 (n52)); 2 (n35)); 3;(n67)); 3 (

我有一份档案

(n34)); 1
Z(n2)); 1
(n52)); 2
(n35)); 3
(n67)); 3
(n19)); 4
(n68)); 4
(n20)); 5
(n36)); 5
(n53)); 5
(n69)); 5
N(n3)); 5
(n54)); 6
(n70)); 7
N(n4)); 7
我希望输出的结果是,只要分号后面有相同的数字,就用字段分隔符打印单行

输出应该是

(n34)); 1;Z(n2)); 1
(n52)); 2
(n35)); 3;(n67)); 3
(n19)); 4;(n68)); 4
(n20)); 5;(n36)); 5;(n53)); 5;(n69)); 5;N(n3)); 5
(n54)); 6
(n70)); 7;N(n4)); 7
我试过下面的代码

awk -F';' 'NR == FNR { count[$2]++;next}
在这方面,我不知道如果存在相同的数字,如何在同一行上打印它。

第一个解决方案:考虑到您的输入文件是按第二列排序的,请您尝试使用GNU awk中显示的示例编写并测试以下内容

awk '
BEGIN{ OFS=";" }
prev!=$2{
  if(val){ print val }
  val=""
}
{
  val=(val?val OFS:"")$0
  prev=$2
}
END{
  if(val){ print val }
}
' Input_file
第二种解决方案:如果第二个字段未排序,请尝试以下方法

sort -nk2 Input_file | 
awk '
BEGIN{ OFS=";" }
prev!=$2{
  if(val){ print val }
  val=""
}
{
  val=(val?val OFS:"")$0
  prev=$2
}
END{
  if(val){ print val }
}
'
awk代码说明:

第一种解决方案:考虑到您的输入文件是按第二列排序的,请您尝试使用GNU awk中显示的示例编写并测试以下内容

awk '
BEGIN{ OFS=";" }
prev!=$2{
  if(val){ print val }
  val=""
}
{
  val=(val?val OFS:"")$0
  prev=$2
}
END{
  if(val){ print val }
}
' Input_file
第二种解决方案:如果第二个字段未排序,请尝试以下方法

sort -nk2 Input_file | 
awk '
BEGIN{ OFS=";" }
prev!=$2{
  if(val){ print val }
  val=""
}
{
  val=(val?val OFS:"")$0
  prev=$2
}
END{
  if(val){ print val }
}
'
awk代码说明:

另一个awk:

$ awk -F\; '{a[$2]=a[$2] (a[$2]==""?"":";") $0}END{for(i in a)print a[i]}' file
输出:

(n34)); 1;Z(n2)); 1
(n52)); 2
(n35)); 3;(n67)); 3
(n19)); 4;(n68)); 4
(n20)); 5;(n36)); 5;(n53)); 5;(n69)); 5;N(n3)); 5
(n54)); 6
(n70)); 7;N(n4)); 7
解释:

$ awk -F\; '{                           # set delimiter (probably useless)
    a[$2]=a[$2] (a[$2]==""?"":";") $0   # keep appending where $2s match
}
END {                                   # in the end
    for(i in a)                         # output
        print a[i]
}' file
编辑:fori将生成随机显示的顺序。如果需要订购,可以通过管道将输出发送到:

$ awk '...' | sort -t\; -k2n
另一个awk:

$ awk -F\; '{a[$2]=a[$2] (a[$2]==""?"":";") $0}END{for(i in a)print a[i]}' file
输出:

(n34)); 1;Z(n2)); 1
(n52)); 2
(n35)); 3;(n67)); 3
(n19)); 4;(n68)); 4
(n20)); 5;(n36)); 5;(n53)); 5;(n69)); 5;N(n3)); 5
(n54)); 6
(n70)); 7;N(n4)); 7
解释:

$ awk -F\; '{                           # set delimiter (probably useless)
    a[$2]=a[$2] (a[$2]==""?"":";") $0   # keep appending where $2s match
}
END {                                   # in the end
    for(i in a)                         # output
        print a[i]
}' file
编辑:fori将生成随机显示的顺序。如果需要订购,可以通过管道将输出发送到:

$ awk '...' | sort -t\; -k2n
救命啊

perl -ne '($x, $y) = split;
          $h{$y} .= "$x $y;";
          END { print $h{$_} =~ s/;$/\n/r for sort keys %h }
         ' -- file
它将每一行置于空白处,将值存储在由第二列键入的哈希表%h中,当文件被读取时,它将打印记住的值,并按第二列对其进行排序。我们总是将分号存储在末尾,因此我们需要在输出中用新行替换最后一行。

perl -ne '($x, $y) = split;
          $h{$y} .= "$x $y;";
          END { print $h{$_} =~ s/;$/\n/r for sort keys %h }
         ' -- file
它将每一行置于空白处,将值存储在由第二列键入的哈希表%h中,当文件被读取时,它将打印记住的值,并按第二列对其进行排序。我们总是将分号存储在末尾,因此我们需要在输出中用新行替换最后一行。

我将使用GNU AWK数组来完成下面的任务。将file.txt内容设置为:

(n34)); 1
Z(n2)); 1
(n52)); 2
(n35)); 3
(n67)); 3
(n19)); 4
(n68)); 4
(n20)); 5
(n36)); 5
(n53)); 5
(n69)); 5
N(n3)); 5
(n54)); 6
(n70)); 7
N(n4)); 7
然后:

输出为:

(n34)); 1;Z(n2)); 1
(n52)); 2
(n35)); 3;(n67)); 3
(n19)); 4;(n68)); 4
(n20)); 5;(n36)); 5;(n53)); 5;(n69)); 5;N(n3)); 5
(n54)); 6
(n70)); 7;N(n4)); 7
说明:我利用GNU AWK数组是惰性的事实,并记住插入顺序并不是在所有AWK中都有保证。对于每一行,我使用;,将整行连接到数组数据中$2键下的内容;。如果尚未存储值,则该值与空字符串相同。这导致了;出现在数据中每个记录的开头,所以我从第二个字符开始打印它。请记住,此解决方案将所有内容都存储在数据中,因此对于大型文件可能无法正常工作

在gawk 4.2.1中进行测试后,我将使用GNU AWK阵列来完成以下任务。将file.txt内容设置为:

(n34)); 1
Z(n2)); 1
(n52)); 2
(n35)); 3
(n67)); 3
(n19)); 4
(n68)); 4
(n20)); 5
(n36)); 5
(n53)); 5
(n69)); 5
N(n3)); 5
(n54)); 6
(n70)); 7
N(n4)); 7
然后:

输出为:

(n34)); 1;Z(n2)); 1
(n52)); 2
(n35)); 3;(n67)); 3
(n19)); 4;(n68)); 4
(n20)); 5;(n36)); 5;(n53)); 5;(n69)); 5;N(n3)); 5
(n54)); 6
(n70)); 7;N(n4)); 7
说明:我利用GNU AWK数组是惰性的事实,并记住插入顺序并不是在所有AWK中都有保证。对于每一行,我使用;,将整行连接到数组数据中$2键下的内容;。如果尚未存储值,则该值与空字符串相同。这导致了;出现在数据中每个记录的开头,所以我从第二个字符开始打印它。请记住,此解决方案将所有内容都存储在数据中,因此对于大型文件可能无法正常工作

在gawk 4.2.1中测试,datamash具有类似的内置功能:

<infile datamash -W groupby 2 collapse 1
datamash具有类似的内置功能:

<infile datamash -W groupby 2 collapse 1

这可能适用于GNU sed:

sed -E ':a;N;s/( \S+)\n(.*\1)$/\1;\2/;ta;P;D' file
将以下行附加到当前行

如果两行都以相同的数字字符串结尾,请删除中间的换行符并重复


打印/删除图案空间中的第一行并重复。

这可能适用于GNU-sed:

sed -E ':a;N;s/( \S+)\n(.*\1)$/\1;\2/;ta;P;D' file
将以下行附加到当前行

如果两行都以相同的数字字符串结尾,请删除中间的换行符并重复

打印/删除图案空间中的第一行并重复