申し訳ありません。クエリを正しく表現していないため、例を修正する必要がありました。 .txtファイルがあるとしましょう。
Happy sad
Happy sad
Happy sad
Sad happy
Happy sad
Happy sad
Mad sad
Mad happy
Mad happy
一意の文字列を削除したいです。ファイルを残してください:
Happy sad
Happy sad
Happy sad
Happy sad
Happy sad
Mad happy
Mad happy
私はソートが重複()を削除できることを知っていますsort file.txt | uniq
。それでは、bashでその逆を実行するためにコマンドを使用できますか?それともwhileループを調べる必要がありますか?ところでuniq -D file.txt > output.txt
動作しません。
答え1
使用awk
:
$ awk 'seen[$0]++; seen[$0] == 2' file
Happy sad
Happy sad
Happy sad
Happy sad
Happy sad
Mad happy
Mad happy
これは、各行のテキストを連想配列のキーとして使用しますseen
。最初は、以前に見たseen[$0]++
行が印刷されるようにします。なぜなら、その行に関連付けられた値は、2行目以降の行が表示されたときにゼロではないからです。seen[$0] == 2
その行が2番目に表示されている場合は、その行が再印刷されます(それ以外の場合は、繰り返される各行の1つの項目を見逃す可能性があります)。
awk '!seen[$0]++'
時々使われるのと似ています。 削除するソートせずに繰り返します(例:awk '!a[$0]++' はどのように機能しますか?)。
重複行のコピーを1つだけ取得します。
awk 'seen[$0]++ == 1' file
または、
sort file | uniq -d
答え2
重複した項目が連続的でなく入力順序を維持する必要がある場合は、awk
2つのパスを使用してこれを実行できます。 1 つは発生回数を計算し、もう 1 つは最初のパスで複数回表示される行を印刷することです。
awk 'second_pass {if (c[$0] > 1) print; next}
{c[$0]++}' file.txt second_pass=1 file.txt
答え3
からman uniq
:
-D すべての重複ライン印刷
次のように目標を達成できます。
uniq -D file.txt
答え4
uniq
これは「オプション」を使用しているため、Linux専用のソリューションである可能性があります-u
。別のバージョンを実行している場合は、uniq -c
フィルタリングなどを使用してこの問題を解決できます。^ *1
sort < in | uniq --unique | grep --invert-match --line-regexp --fixed-strings --file - in
最初のステップ2が始まります。
Mad sad
Sad happy
次の手順では、これらの行に正確に一致する行を削除します。私は明確にするために長いオプションを選択しました。私はめったに使用されておらず、短い形式は次のとおりです。sort < in | uniq -u | grep -v -x -F -f - in