文字列が特殊文字列(カンマまたは区切り文字ではない)で区切られたファイルがあります<vvv>
。たとえば、最初のフィールドのすべての文字列が一意であることを確認したいとします。同じフィールドに重複行が見つかった場合は、重複行をすべて削除したい(最初の項目を保持)。
例:
aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
aaa<vvv>new<vvv>new2
111<vvv>222<vvv>333
私は欲しい:
aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
111<vvv>222<vvv>333
すでに現れたaaa<vvv>new<vvv>new2
ので削除しました。aaa
awk
私はそれが唯一の解決策ではない場合、私たちは好きではありません。 Linuxに慣れていない私にとっては、構文は少し複雑です。
ベストアンサー1
使用しないでくださいawk
非常に:
$ awk -v OFS="<" '{ print NR, $0 }' file | sort -t '<' -u -k2,2 | sort -t '<' -k1,1n | cut -d '<' -f 2-
aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
111<vvv>222<vvv>333
これは、元のデータにawk
行番号を挿入するためにのみ使用されます。<
これにより、元の行の順序を追跡できます。<
行番号と行の残りの部分の区切り記号として使用する理由は、元の最初のフィールドと行の残りの部分の区切り文字としても表示されるためです。
パイプラインの最初のステップを使用してawk
行番号を挿入した後、データは次のようになります。
1<aaa<vvv>bbb<vvv>ccc
2<xxx<vvv>yyy<vvv>zzz
3<aaa<vvv>new<vvv>new2
4<111<vvv>222<vvv>333
パイプラインの次のステップでは、それを2番目のフィールド(最初のソースフィールド)で並べ替えて重複エントリを削除します。結果は次のとおりです。
4<111<vvv>222<vvv>333
1<aaa<vvv>bbb<vvv>ccc
2<xxx<vvv>yyy<vvv>zzz
2つ目は、sort
最初のフィールドの行を数字でソートして元の行の順序を復元します。
1<aaa<vvv>bbb<vvv>ccc
2<xxx<vvv>yyy<vvv>zzz
4<111<vvv>222<vvv>333
次に、cut
最初のフィールド(および挿入された区切り文字)から数字を削除します。
を使用せずにソートされた出力を提供するソリューションawk
は次のとおりです。
$ sort -t '<' -u -k1,1 file
111<vvv>222<vvv>333
aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
これは本質的に上記のパイプラインの2番目のステップであり、重複エントリを削除しながら最初のフィールドのファイルをソートします。
解決策awk
は次のとおりです。
$ awk -F '<' '!seen[$1]++' file
aaa<vvv>bbb<vvv>ccc
xxx<vvv>yyy<vvv>zzz
111<vvv>222<vvv>333
これは、最初のフィールドを名前付き連想配列のキーとして保存seen
し、その後に関連する値を増やします。与えられたキーの配列の値が0の場合(つまり、最初のフィールドが以前に見たことがない場合)、その行を印刷します。