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
将以下行附加到当前行
如果两行都以相同的数字字符串结尾,请删除中间的换行符并重复
打印/删除图案空间中的第一行并重复