ファイル内で一意でないすべての行を見つけるには、uniqを使用しようとします。一意ではないということは、前の行ですでに見たすべての行を意味します。私の考えでは、「-D」オプションは次のような役割を果たします。
-D print all duplicate lines
しかし、繰り返し行を印刷する代わりにみんな複数行があるとき。行の2番目とそれ以降のコピーだけを印刷したいです。
どうすればいいですか?
答え1
小文字の-dオプションのGNUバージョンが必要です。
# printf "a\na\na\nb\nb\nc\n" | uniq -d
a
b
答え2
GNUまたはast-openを使用して実装されますuniq
。
uniq -D -u < input
(-D
それ自体は非標準です)が、これは最初のものではなく、削除する最後の冗長性であることに注意してください(-i
、または使用すると-w
違いが発生します-f
)。
移植可能な場合は、いつでも次のものを使用できますawk
。
awk 'NR > 1 && $0 "" == previous ""; {previous = $0}' < input
(isと連結すると、""
オペランドが数字のように見えても文字列比較が強制されます。)
最初の9文字だけを比較します(これも-w
GNU拡張であり、(現在)文字ではなくバイトで動作することに注意してください(文書にそのように記載されています))。
awk '{current = substr($0, 1, 9)}
NR > 1 && current == previous
{previous = current}' < input
""
(この場合、substr()
文字列が返されるため、接続は不要です。)
UTF-8ロケールからの出力時
printf '%s\n' StéphaneChazelas StéphaneUNIX StéphaneUnix
StéphaneUnix
期待どおりに while uniq -w9 -D -u
(GNU を使用uniq
) を提供しStéphaneChazelas
、-isでStéphaneUNIX
8Stéphane
文字を提供しますが、UTF-8 では 9 バイトを提供しますが、ast-openuniq
は StéphaneUNIX (awk
最初の項目をスキップ、uniq
最後の項目を一度削除) のみを提供します。
を使用すると、awk
次の項目に隣接していなくても、すべての重複行を報告できます。
awk 'seen[$0]++' < input
(メモリ内のすべての一意の行をハッシュテーブルに保存します。)
または、最初の9文字だけを考慮してください。
awk 'seen[substr($0, 1, 9)]++' < input
答え3
解決策はuniqを使用し-c
てから必要なものを削除することです。
e444$ ( echo a ; echo a ; echo b ; echo d ; echo d ; echo e ) | uniq -c
2 a
1 b
2 d
1 e
a
繰り返しd
て二重b
にe
e444$ ( echo a ; echo a ; echo b ; echo d ; echo d ; echo e ) | uniq -c \
| sed -E '/^ *1 .$/d;s/^ *[0-9]+ //'
表現の説明sed
:
/^ *1 .$/d
すべての一意の行を削除します
s/^ *[0-9]+ //
カウンターが削除されます