我有一个文件,其布尔值设置为下一行显示的文件位置。我需要更改'删除'对于包含' trash'的所有文件路径,值为1在他们中。我正在尝试使用sed来完成这项任务。
我很难获得模式引用(即。\ 1)以正确输出
请参阅下面的文件示例:
delete: 0
filepath: Downloads/trash/foo1
delete: 0
filepath: Downloads/keep/foobar
delete: 0
filepath: Downloads/trash/foofoofoo
这就是我对sed功能所拥有的。我试图通过\ 1稍后引用第二行作为引用,但它输出为' 1'。
sed -e '
/delete)/{
N
/\(.*trash.*\)/c \
delete: 1
\1
}' test.txt > test2.txt
输出:
delete: 1
1
delete: 0
filepath: Downloads/keep/foo1
delete: 1
2
我看到我想要的两条线都发生了变化,所以我知道我在模式空间中取出了正确的线条。但第二行输出不正确。我也知道这种类型的语法在单行替换中工作正常,但在这种多行情况下不行。
任何帮助将不胜感激。谢谢。
答案 0 :(得分:2)
这可能适合你(GNU sed):
sed '/^delete/{N;/trash/s/delete: 0/delete: 1/}' file
这会查找以delete
开头的行,然后附加下一行并查找trash
,如果是,则用delete: 0
替换delete: 1
N.B。您不能仅在i
中的a
,c
或s/.../.../
命令中使用反向引用
见here。
答案 1 :(得分:2)
sed是用于涉及多行的任何问题的错误工具。这就是awk的用途:
$ awk '!(NR%2){print "delete:", (/trash/?1:0) ORS $0}' file
delete: 1
filepath: Downloads/trash/foo1
delete: 0
filepath: Downloads/keep/foobar
delete: 1
filepath: Downloads/trash/foofoofoo
或者由于其他原因,您现有的删除值可能不为零:
$ awk 'NR%2{d=$NF;next} {print "delete:", (/trash/?1:d) ORS $0}' file
delete: 1
filepath: Downloads/trash/foo1
delete: 0
filepath: Downloads/keep/foobar
delete: 1
filepath: Downloads/trash/foofoofoo
答案 2 :(得分:0)
$ sed -i '$!N;s/^delete: 0\(\nfilepath:.*\/trash\/.*\)$/delete 1\1/i;P;D' test.txt
delete 1
filepath: Downloads/trash/foo1
delete: 0
filepath: Downloads/keep/foobar
delete 1
filepath: Downloads/trash/foofoofoo
$