perl + 忽略带有注释的行并删除带有匹配单词的重复行

perl + 忽略带有注释的行并删除带有匹配单词的重复行

我们创建以下 Perl oneliner。为了删除除第一个匹配行之外的双行,语法的第二部分是忽略带注释“#”的行。

例子:

# more /tmp/test

     # abra_kadabra

abra_kadabra
abra_kadabra


# perl -i -ne -e'next if /^#/; next if /abra_kadabra/ && ++$ok > 1; print' /tmp/test


# more /tmp/test

     # abra_kadabra

事实上,尽管我们设置了以下内容,Perl 语法并没有忽略注释行next if /^#/1

请建议我的语法有什么问题?

预期产出

# more /tmp/test

     # abra_kadabra

abra_kadabra

其他例子:

# more /tmp/test

     # abra_kadabra
#       abra_kadabra
abra_kadabra 1
abra_kadabra 2
abra_kadabra 3
abra_kadabra 4

预期输出:

# more /tmp/test

     # abra_kadabra
#       abra_kadabra
abra_kadabra 1

答案1

next if /^#/; ...; print表示以 开头的行将#不会被打印。

在这里,你想要

perl -i -ne 'next if !/^\s*#/ && /abra_kadabra/ && $count++; print' /tmp/test

这就是你想要的不是next如果您想保留注释掉的行,请调用它们。

sed与那些支持的实现相同-i-i ''使用 FreeBSD 及其衍生产品):

sed -i -e '/^[[:space:]]*#/b' -e '/abra_kadabra/!b' -e 'x;/./d;g' /tmp/test

我们在哪里使用保留空间记住我们abra_kadabra以前是否已经见过。

答案2

您已将 锚定#为仅在行首匹配。如果您想跳过所有以“#”开头的行,即使在前导空格之后,您需要:

next if /^\s*#/

这将跳过带有可选的前导空格后跟#.

相关内容