我们创建以下 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*#/
这将跳过带有可选的前导空格后跟#
.