次の行の最初の列と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,2
cut
次に行を繰り返し、入力からpattern
3番目の列()を収集します。最後に、改行を削除し、一致するものを印刷します。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
説明する
aを設定し、次の行を追加してから、do-while
loop
最初の2つのフィールドをパターンスペースの同じフィールドとpattern space
比較します。newline
パターンスペースから削除できる場合はループを繰り返し、それができない場合はループを終了します。この時点で、最初の改行文字までパターンスペースを印刷します。そしてこの部分を削除してもっと回してください。