是否可以将参数传递给 sed 脚本?

是否可以将参数传递给 sed 脚本?

考虑一个简单的 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从命令行传递的。请注意,有-eafter很重要-f。分隔符也没有什么特别的#,使用通常不会出现在文件中的任何内容。

答案2

是的,你完全可以! -
您可以从 shell 定义变量并在脚本中转义变量名称,类似于此

s/'$replace'/bar/

然后将脚本调用为:

replace="foo" && sed -f script.sed

如果您想将文件作为参数传递,这里的技巧就是让脚本以没有参数的方式结尾,如下所示

/foo/{
  s/foo/bar/
}

然后从 shell 中用xargsor调用它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?

相关内容