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

Ell*_*iew 2 bash sed

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

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

sed -e 's/\(.*\)/<bash_function \1>/'
Run Code Online (Sandbox Code Playgroud)

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

ste*_*ver 5

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

\n\n
\n

e

\n\n

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

\n
\n\n

受以下限制:

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

  2. \n
  3. 你的系统/bin/shbash

  4. \n
  5. 您已导出该函数,如此处所述Can I \xe2\x80\x9cexport\xe2\x80\x9d Functions in bash?

  6. \n
\n\n

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

\n\n
sudo ln -sf bash /bin/sh\n\nfoo() { echo "Doing foo on $1"; }\nexport -f foo\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么我可以做

\n\n
$ echo bar | sed \'s/\\(.*\\)/foo \\1/e\'\nDoing foo on bar\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
echo \'bar; echo xx\' | sed \'s/\\(.*\\)/foo \\1/e\'\nDoing foo on bar\nxx\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
$ echo bar | sed \'s/\\(.*\\)/foo \\1/e\'\nsh: 1: foo: not found\n
Run Code Online (Sandbox Code Playgroud)\n\n

但鉴于

\n\n
$ cat ./myfuncs.sh \nfoo() { echo "Doing foo on $1"; }\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后

\n\n
$ echo bar | sed \'s/\\(.*\\)/. .\\/myfuncs.sh ; foo \\1/e\'\nDoing foo on bar\n
Run Code Online (Sandbox Code Playgroud)\n