考虑一个简单的 sed 脚本foo-to-bar.sed
:
s/foo/bar/
和简单的调用:
sed -f foo-to-bar.sed some-file.txt
现在,假设我想自定义替换字符串(在本例中为 bar)并将其作为参数传递给 sed 脚本。那可能吗?
注意:我知道我可以摆脱 sed 脚本并内联使用 shell 变量。我对将参数传递到 sed 脚本特别感兴趣。我在文档中找不到任何内容,但我仍然希望我遗漏了一些东西。
答案1
由于似乎确实无法传递参数,因此我能想到的最佳解决方法是使用从命令行替换的中间占位符。foo-to-bar.sed
:
s/foo/#ARG1#/
调用:
sed -f foo-to-bar.sed -e "s/#ARG1#/bar/g" some-file.txt
说明:foo
首先替换为#ARG1#
,然后替换为bar
从命令行传递的。请注意,有-e
after很重要-f
。分隔符也没有什么特别的#
,使用通常不会出现在文件中的任何内容。
答案2
是的,你完全可以! -
您可以从 shell 定义变量并在脚本中转义变量名称,类似于此
s/'$replace'/bar/
然后将脚本调用为:
replace="foo" && sed -f script.sed
如果您想将文件作为参数传递,这里的技巧就是让脚本以没有参数的方式结尾,如下所示
/foo/{
s/foo/bar/
}
然后从 shell 中用xargs
or调用它find
并让他们为您替换参数:
find ./shelves -type f \( -name "*.json" -o -name "*.csv" \) -print -exec sed -f main.sed {} \;
有用!
答案3
没有什么好办法,但我看到了解决方法。最好的可能在于使用envsubst
:
a.sed.tpl
:
s/$s/x/
a.sh
:
s=e
echo aoeu | sed -Ef <(cat a.sed.tpl | s=$s envsubst '$s')
$ bash -eu a.sh
aoxu
该值按原样传递。如果您想传递任意字符串并且按字面意思处理它,则需要在运行之前对其进行转义sed
。
似乎已经没有办法逃脱$
了envsubst
。
更多的选择这里。
答案4
您可以在 sed 内部传递参数——只要您在 sed 代码中使用双引号即可。
尝试这个练习:
$ cat infile
Is it possible to pass arguments to a sed script?
$ fsed() { sed "s/pass/$1/g" "$2"; }
$ fsed PASS infile
Is it possible to PASS arguments to a sed script?