私のファイルには複数の列が含まれており、最初の列は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
答え2
awk '
!B {a[$1]++}
B && a[$1] > 1
' B=0 file B=1 file
最初のフィールド(= ID)を取得して並べ替え、IDを統合し、重複した項目のみを保持します。これをxargsに渡し、各IDに基づいてegrep ERE正規表現を作成します。
< file \
cut -d" " -f1 \
| sort | uniq -d \
| xargs -I{} echo ^{}\\s \
| grep -Ef - file \
;
perl
slurpファイルオプションを使用し-0777
てレコードを介して正規表現を実行すると、各行の先頭にさらに下^
の最初のフィールド(= ID)が表示されるか、IDが以前に見つかった場合は現在の行が印刷されます。
perl -0777ne '
() = m/(?msx)
^
(?<line>
(?<ID> A\w+)
\h.*?\n
)
(?=
(?:.*?\n)?
(?<lukahead> \g{ID}|$)
)
(?{ my %seen;
my($id_visible_ahead, $id_already_seen) =
map { $_ > 0 }
length($+{lukahead}), $seen{$+{ID}};
print($+{line}),$seen{$+{ID}}++
if $id_visible_ahead || $id_already_seen;
})
/g;
' file
出力:
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB
A2SGWS7CUGU8GB