我正在寻找一种从一堆文件中删除特定行的方法,但前提是该行在该文件中出现多次。其他行应保留,即使它们是重复的。
例如,像这样的文件,我想删除重复项AAA
AAA
BBB
AAA
BBB
CCC
应该成为
AAA
BBB
BBB
CCC
我想我应该使用,sed
但我不知道如何编写命令。
答案1
使用 GNU sed
:
sed '0,/^AAA$/b;//d'
也就是说,让所有内容通过(b
像 a 一样分支continue
)直到第一AAA
行(从第 0 行(甚至在第一行之前)和第一个匹配的行/^AAA$/
(可能是第一行)),然后是剩余的行,删除所有出现的AAA
(空//
模式重复使用最后一个模式)。
sed
地址需要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
对于包含一些正则表达式的给定 shell 变量。
如果$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