最初の列の重複行を削除

最初の列の重複行を削除

文字列が特殊文字列(カンマまたは区切り文字ではない)で区切られたファイルがあります<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の場合(つまり、最初のフィールドが以前に見たことがない場合)、その行を印刷します。

おすすめ記事