特定の列のすべてのファイルにパターンが一度だけ含まれている場合に行を削除する方法

特定の列のすべてのファイルにパターンが一度だけ含まれている場合に行を削除する方法

私のファイルには複数の列が含まれており、最初の列はIDに対応しています。ファイル全体でIDが一度だけ表示される場合(最初の列)、行を削除したいと思います。 IDが何度も表示される場合は、その行をファイルに保存したいと思います。 IDはAで始まる文字(時には数字)で構成されています(他のすべての文字/数字はランダムな順序です)。たとえば、A2SGWS7CUGU8GB

私が持っているなら:

# id             #column 2 ...
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB
ADE8GST9URWPOS
ABXLMWJCQFGVXV
A2SGWS7CUGU8GB

ADE8GST9URWPOSと を含む行はABXLMWJCQFGVXV一度だけ表示されるので、削除したいと思います。どうすればいいですか?

ベストアンサー1

まず、保持したいすべての冗長IDが返されます。

$ awk '{ print $1 }' <file | sort | uniq -d
A2SGWS7CUGU8GB

を使用して、最初のスペースで区切られたフィールド(ID)を抽出してこれを実行しますawk。その後、それらをソートしてuniq -d重複したIDのみを出力するために使用されます。

その後、これらの(この場合は単一の)IDを使用して元のファイルからその行を抽出できます。まず、次のようにソートする必要がありますjoin

$ join <( awk '{ print $1 }' <file | sort | uniq -d ) <( sort file )
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB

シェルが<(...)一時ファイルを使用したプロセスの置き換えをサポートしていない場合は、一時ファイルを使用して2つのステップでこれを実行できます。

$ sort -o file.sorted file
$ awk '{ print $1 }' <file | sort | uniq -d | join - file.sorted
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB

使用ただ awk、これは次のように行うことができます。

$ awk 'NR == FNR { count[$1]++; next } count[$1] > 1' file file
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB

コードはファイルを2回読み取るため、コマンドラインでファイルを2回参照しますawk

最初は、連想配列がcount各IDの発生回数で満たされ、第2に、IDが複数回発生する各行が出力される。

上記の2つの方法の違いは、awk最後のコマンドが元のデータの順序を維持しますが、一意のIDの数に比例してメモリを消費することです。最初のアプローチはソートされた結果を生成するため、より適している可能性があります。とても大きいデータ。


ヘッダー行を保持するには、コマンドを少し変更する必要があります。

$ join <( awk '{ print $1 }' <file | sort | uniq -d ) <( sort file ) | cat <(head -1 file) -

または

$ sort -o file.sorted file
$ awk '{ print $1 }' <file | sort | uniq -d | join - file.sorted > file.noheader
$ head -1 file | cat - file.noheader

または

$ awk 'NR == 1 ; NR == FNR { count[$1]++; next } count[$1] > 1' file file

おすすめ記事