我在一个变量中存储了 3 行数字,我需要用它来替换我已使用并存储在另一个变量中$new
的文件中的 3 行。我想。但我收到错误:grep
$old
sed "s/$old/$new/g" input > output
sed: 1: "s/\( 28.47969107 0. ...": unterminated substitute pattern
我的输入文件如下所示:
scale
1.000
primitive lattice vectors
28.47969107 0.00000000 0.00000000
0.00000000 28.47969107 0.00000000
0.00000000 0.00000000 28.47969107
grid dimensions
100 100 100
我的$old
是线条
28.47969107 0.00000000 0.00000000 0.00000000 28.47969107 0.00000000 0.00000000 0.00000000 28.47969107
$new
与旧的格式相同,只是数字不同。
答案1
sed -e "/$old/i$new" -e "/$old/{N;N;d}" input > output
在哪里
$old
可以是28.47969107
第一行,也可以是第一行28.47969107 0.00000000 0.00000000
$new
应该是形式28.47969107 0.00000000 0.00000000\n0.00000000 28.47969107 0.00000000\n0.00000000 0.00000000 28.47969107
其他方式(如果你有新的 GNU sed (版本 >4.2.1)和选项)在变量中-z
转义:newline
sed -z "s/$(printf "%b" "$old"|sed '$!s/$/\\/')/$(printf "%b" "$new"|sed 's/$/\\/')/" input > output
或者,如果您在脚本分配函数中进行替换
end_esc(){ printf "%b" "$@"|sed '$!s/$/\\/' ; }
sed -z "s/$(end_esc $old)/$(end_esc $new)/" input > output
答案2
首先,让我们定义一个示例字符串new
:
$ new=$'1 2 3\n4 5 6\n7 8 9'
现在,让我们删除后面的三行primitive lattice vectors
并将其替换为new
:
$ awk -v "new=$new" 'f==1{print new} f{f--;next} {print} /primitive/{f=3}' input
scale
1.000
primitive lattice vectors
1 2 3
4 5 6
7 8 9
grid dimensions
100 100 100
答案3
sed -e '$!N;$b' -e "/\n.*\n/!N;s/$old/$new/;t" -e P\;D
上面的代码可以工作,但有一个问题:换行符 in$old
需要表示为\n
,换行符 in$new
前面应该有一个\
反斜杠。你的价值观中的换行符给你带来了麻烦。例如,扩展后:
sed 's/24.0000000001
.000000000000
.0000000000/...'
...不起作用。那是一个未终止的正则表达式- 你看?
反而:
old='num\nnum\nnum'
new='num\
num\
num'
...就是你所需要的。
如果出于某种原因,您发现自己逃避变量很麻烦,那么您可以执行以下操作:
( set -f; IFS='
'; printf '%s\\n' / .* '/!N;s/'$old
printf '%s\\\n' */$new"/;t$IFS#"
)| sed -e '$N;$b' -f - -e P\;D input > output
但这取决于两个变量中没有空行,而且可能并不容易。
答案4
sed s/"$old"/"$new"/g
为我工作