如何将 bash 函数嵌入到 sed 表达式中?

如何将 bash 函数嵌入到 sed 表达式中?

在 sed 中如何使用 bash 函数创建替换字符串,尤其是一个或多个已找到部分的函数,通常标识为 \1、\2、...?

换句话说,我想做这样的事情:

sed -e 's/\(.*\)/<bash_function \1>/'

注意:这个Q类似于如何将 shell 命令嵌入到 sed 表达式中?,但我不想调用 GNU/Linux 命令,而是想简单地调用本地 bash 函数。

答案1

您可以使用 GNU sed 来执行此操作,使用以下e标志:

e

该命令允许将 shell 命令的输入通过管道传送到模式空间。如果进行了替换,则执行在模式空间中找到的命令,并用其输出替换模式空间。尾随换行符被抑制;如果要执行的命令包含 NUL 字符,则结果未定义。这是一个 GNU sed 扩展。

受到以下限制:

  1. 然后,整个结果“模式空间”(即搜索和替换后的整个输入字符串)将被执行,即不仅仅是最后两个斜杠之间的内容。这就是您在示例中显示的内容,但可能不是您真正想要做的。

  2. 你的系统/bin/shbash

  3. 您已导出该函数,如此处所述我可以在 bash 中“导出”函数吗?

例如,在我的系统上(默认情况下/bin/shshell 在哪里dash),步骤是

sudo ln -sf bash /bin/sh

foo() { echo "Doing foo on $1"; }
export -f foo

那么我可以做

$ echo bar | sed 's/\(.*\)/foo \1/e'
Doing foo on bar

下面是另一个示例,进一步阐明执行搜索和替换后执行的整个输入字符串:

echo 'bar; echo xx' | sed 's/\(.*\)/foo \1/e'
Doing foo on bar
xx

如果您无法安排 to /bin/shbe bash,那么您最接近的可能是将函数定义放在文件中并首先获取它:

$ echo bar | sed 's/\(.*\)/foo \1/e'
sh: 1: foo: not found

但鉴于

$ cat ./myfuncs.sh 
foo() { echo "Doing foo on $1"; }

然后

$ echo bar | sed 's/\(.*\)/. .\/myfuncs.sh ; foo \1/e'
Doing foo on bar

相关内容