替换、打印和删除文件中的行

替换、打印和删除文件中的行

我正在使用 sed 执行以下操作:

  • 匹配模式(例如:以 开头的行#
  • 替换匹配(例如:将#开头的字符替换为空/将其删除)
  • 打印到标准输出(例如:将结果替换打印到标准输出,因为我们正在使用-i
  • #删除匹配(例如:删除行首包含字符的整行)

这是在文件上完成的,因此,sed与标志一起使用时不会输出到标准输出-i,除非我使用以下内容诡计:

sed -i -e 's/^\(#\)/\1/w /dev/stdout' -e '/^#/d' test

在名为 的文件上test,包含以下示例内容:

#this
#is
a
test

以上适用于一切,除了替换...这里是实现替换的一个(我尝试在#将字符打印到标准输出之前删除该字符):

sed -i -e 's/^\(#\)//w /dev/stdout' -e '/^#/d' test

这与上面类似,除了我替换\1//所以它删除#而不是打印整行......

问题是,最后一个不起作用删除行,而只是替换并打印。第一个确实适用于除替换之外的所有内容(例如:删除#行开头的符号)

为什么这不起作用(第二次尝试,即第一次尝试有效,只是它不删除字符#)?

答案1

第一个表达式删除了第二个表达式可能匹配的s/^\(#\)//w /dev/stdout内容。/^#/d

你可以改为使用

sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test

前任。

$ cat test
#this
#is
a
test

$ sed -i -e '/^#/{s///w /dev/stdout' -e 'd}' test
this
is

$ cat test
a
test

答案2

GNU awk

awk  -i inplace '{if (/^#/) {sub(/^#/, "");arr[++i]=$0;} else print}END{for (a in arr) print arr[a]}' input

选项-i--include用于包含awk源库inplace

关于inplace阅读

inplace 扩展模拟 GNU sed 的-i选项,该选项对每个输入文件执行“就地”编辑。

if (/^#/)这会查看是否有以 开头的行#。如果找到则sub()替换#为空字符串。现在进行替换并创建$0一个数组。arr该数组是按END块打印的,因此会打印在屏幕上。正在打印的其他行(在main块中)通过 发送到文件inplace

$ awk  -i inplace '{if (/^#/) {sub(/^#/, "");arr[++i]=$0;} else print}END{for (a in arr) print arr[a]}' input
this
is

$ cat input
a
test

相关内容