awkで最後の行を繰り返したいですか?

awkで最後の行を繰り返したいですか?

私はファイルを持っています:

key value

blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1

重複した行を削除するには、次の手順を実行します。

awk '/man1/ { print $1,$2} ' file | awk '!x[$0]++'

このコマンドは最初の行を取得し、他の行は無視します。

man1 boy1 
man1 boy2

しかし、最後の行を除くすべての行を無視したいと思います。

man1 boy2 
man1 boy1

Rameshが言ったように、私は次のようなものが欲しい。

cat filename
blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1
man1 boy2
man1 boy3
man1 boy4
man1 boy2

希望の出力

man1 boy1
man1 boy3
man1 boy4
man1 boy2

答え1

tac filename |awk '/man1/ { print $1,$2} '| awk '!x[$0]++' | tac 

テスト

もっと具体的な入力でテストしたいです。だから私のテストは次のようになります。

cat filename
blah blah
blah blah
blahblah
man1 boy1
blah blah
man1 boy2
man1 boy1
man1 boy2
man1 boy3
man1 boy4
man1 boy2

ここで上記のコマンドを実行し、出力を取得します。

tac filename |awk '/man1/ { print $1,$2} '| awk '!x[$0]++' | tac
man1 boy1
man1 boy3
man1 boy4
man1 boy2

awkSteeldriverが提案したように、次のように簡単に変更できます。

tac filename | awk '/^man1/ && !x[$2]++' | tac

答え2

次のシェルスクリプトを使用してこれを実行できます。

#!/bin/bash
awk '/man1/{pos[$0] = NR}
END {
  for(key in pos) reverse[pos[key]] = key
  for(nr=1;nr<=NR;nr++)
    if(nr in reverse) print reverse[nr]
}' yourfile

出力:

[root@host ~]# sh shell.sh
man1 boy1
man1 boy3
man1 boy4
man1 boy2

源泉

答え3

そしてzsh

$ printf '%s\n' ${(Oau)${(MOa)${(f)"$(<file)"}:#man1*}}
man1 boy1
man1 boy3
man1 boy4
man1 boy2

人々はパラメータ拡張フラグ:

  • f:改行に分割
  • ${(M)array:#pattern}:パターンに一致する要素に展開されます。
  • Oa: 配列の順序を逆にする
  • u:ユニーク

答え4

2段階のソリューション。最初のパスでは、各キーの最後のレコードのレコード番号を配列としてキャプチャします。 2番目のパスでレコード番号が配列にある場合は印刷します。

awk 'NR == FNR{if ($0 ~ /man/)x[$0]=NR; next};
     FNR == 1{for (k in x) y[x[k]]=k};
     (FNR in y)' file file
man1 boy1
man1 boy3
man1 boy4
man1 boy2

関連情報