如果下一行的第一列和第二列与当前行相同,我想将每行的最后一列打印到当前行。
我的输入文件是
A 123 BC
A 123 DD
A 123 TT
B 456 AA
B 456 RR
C 789 EE
期望的输出是
A 123 BC DD TT
B 456 AA RR
C 789 EE
答案1
awk
:
awk '{a[$1FS$2]=a[$1FS$2]FS$NF} END {for(i in a) print i a[i]}'
a[$1FS$2]=a[$1FS$2]FS$NF
将关联数组的键设置为由字段分隔符分隔的前两个字段,并将值设置为通过字段分隔符连接到前一个值的最后一个字段END {for(i in a) print i a[i]}
在最后执行,它迭代数组的键a
并打印键和各自的值
例子:
% cat file.txt
A 123 BC
A 123 DD
A 123 TT
B 456 AA
B 456 RR
C 789 EE
% awk '{a[$1FS$2]=a[$1FS$2]FS$NF} END {for(i in a) print i a[i]}' file.txt
A 123 BC DD TT
B 456 AA RR
C 789 EE
答案2
这是一种方法,与GNU 数据混合
$ datamash -Ws groupby 1,2 collapse 3 < file | sed 's/[,\t]/ /g'
A 123 BC DD TT
B 456 AA RR
C 789 EE
该sed
命令用空格替换默认字段和折叠分隔符。
答案3
首先是前两列和第三列上的sort
输入行file
和唯一 ( ) 行。-u
-k1,2
cut
然后迭代 in 行并从 input 中pattern
收集第三列 ( ) 。最后删除换行符并打印匹配项。sed
file
tr
pattern=$(sort -k1,2 -u < file | cut -d' ' -f1-2)
while read -r line
do
collect=$(sed -n 's/^'"$line"'//p' file | tr '\n' ' ')
echo "$line $collect"
done <<<"$pattern"
答案4
sed -E '
:loop
$!N
s/^(((\S+\s+){2}).*)\n\2/\1 /
tloop
P;D
' yourfile
结果
A 123 BC DD TT
B 456 AA RR
C 789 EE
解释
我们设置 ado-while
loop
并将下一行附加到 ,然后将前两个字段与模式空间中的pattern space
相同字段进行比较。newline
如果它们能够从模式空间中删除,那么我们重复循环,如果无法这样做则退出循环。此时,我们将模式空间打印到第一个换行符。并删除这部分并返回更多。