如何在模式匹配后打印当前行的下一个第 n 列?

如何在模式匹配后打印当前行的下一个第 n 列?

如果下一行的第一列和第二列与当前行相同,我想将每行的最后一列打印到当前行。

我的输入文件是

 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,2cut

然后迭代 in 行并从 input 中pattern收集第三列 ( ) 。最后删除换行符并打印匹配项。sedfiletr

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如果它们能够从模式空间中删除,那么我们重复循环,如果无法这样做则退出循环。此时,我们将模式空间打印到第一个换行符。并删除这部分并返回更多。

相关内容