複数のファイルから特定の行を削除する方法を探していますが、その行がそのファイルに複数回表示される場合にのみ可能です。他の行は重複しても維持する必要があります。
たとえば、このようなファイルの場合は、重複したファイルを削除したいと思います。AAA
AAA
BBB
AAA
BBB
CCC
しなければならない
AAA
BBB
BBB
CCC
使用する必要があるようですが、sed
命令をどのように書くべきかわかりません。
答え1
GNUの使用sed
:
sed '0,/^AAA$/b;//d'
つまり、最初の行(行0(最初の行より前でも)と最初の一致行(最初の行にすることができます))まですべてを通過(b
aのように分岐)し、残りの行からすべての項目を削除します。 (空のパターンは最後のパターンを再利用します)continue
AAA
/^AAA$/
AAA
//
sed
AddressにはGNUが必要です(同じ式でコマンドの後に他のコマンドを含めることができる0
機能もありますが、これは両方の式を使用して異なる実装で簡単に解決できます)。b
-e
そしてawk
:
awk '$0 != "AAA" || !n++'
(または正規表現パターンの場合awk '!/^AAA$/ || !n++'
:)
略語:
awk '! (&0 == "AAA" && count > 0) {print; count++}'
答え2
Stéphane Chazelasのawk
ソリューション美しい:
awk '!/AAA/ || !n++' file.in
これは次のように要約できます。
awk '$0 !~ pattern || !n++' pattern="$pattern" file.in
$pattern
一部の正規表現を含む特定のシェル変数の場合。
バックスラッシュを含む場合は、$pattern
エスケープ処理(\\
)する必要があります。または、次のものを使用できます。
P="$pattern" awk '$0 !~ ENVIRON["P"] || !n++' file.in
答え3
行が現れるたびにバッファを交換し、パターン空間に同じ行が含まれている場合は削除し、そうでない場合は保持されているバッファから行を検索します。
sed -e '/^AAA$/{x;//d;g' -e'}' infile
または
sed '/^AAA$/{
x
//d
g
}' infile