パターンマッチング後に現在の行の次のn番目の列を印刷する方法は?

パターンマッチング後に現在の行の次のn番目の列を印刷する方法は?

次の行の最初の列と2番目の列が現在の行と同じ場合、各行の最後の列を現在の行に印刷したいと思います。

私の入力ファイルは

 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連想配列のキーをフィールド区切り文字で区切った最初の 2 つのフィールドに設定し、値をフィールド区切り文字で前の値に関連付けられた最後のフィールドに設定します。

  • 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最初に入力行と最初の2列と3列目のfile一意()行です。-u-k1,2cut

次に行を繰り返し、入力からpattern3番目の列()を収集します。最後に、改行を削除し、一致するものを印刷します。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

説明する

aを設定し、次の行を追加してから、do-while loop最初の2つのフィールドをパターンスペースの同じフィールドとpattern space比較します。newlineパターンスペースから削除できる場合はループを繰り返し、それができない場合はループを終了します。この時点で、最初の改行文字までパターンスペースを印刷します。そしてこの部分を削除してもっと回してください。

関連情報