如何在多个调用的变量中保存 sed 语句(带引号)

How to save sed statement (with quotes) in a variable for multiple calls

我使用以下管道对某些文本进行后处理:

sed 's/error/     /g' | sed 's/\+/ /g' | tail -n +6 | ghead -n -1

我需要多次使用这个管道,所以我想将所有这些保存在一个变量中,以便以后可以轻松调用它。我尝试了几种不同的方式来保存引号(单引号、双引号、转义引号等),例如:

cleanup='sed '"'"'s/error/     /g'"'"' | sed '"'"'s/\+/ /g'"'"' | tail -n +6 | ghead -n -1'

不过,到目前为止我还没有找到神奇的组合。

编辑======

显然,我真正的问题是我没有使用 eval。但是,我仍然对比我更优雅的方法感兴趣。

如果 cleanup 是一个函数,而不是一个字符串,它会起作用:

cleanup() { sed 's/error/     /g' | sed 's/\+/ /g' | tail -n +6 | ghead -n -1; }

举个例子:

$ seq 8 | cleanup
6
7

简化

看来流水线可以简化了。如果我不熟悉的ghead和通常的head一样,那么试试:

cleanup() { sed '1,5d; $d; s/error/     /g; s/\+/ /g'; }

其工作原理如下:

  • 1,5 d 删除第一行到第五行。这将替换 tail -n +6.

  • $d 删除最后一行。这将替换 head -n -1.

  • 两个替换命令保持不变,但合并到这次 sed 调用中。

非 GNU sed(BSD,Mac OSX)

以上是在 GNU sed 上测试的。 NeronLeVelu 报告说其他 sed 版本可能需要在删除命令后使用换行符。在这种情况下,使用 bash 的 $'...' 功能,尝试:

cleanup() { sed $'1,5d\n $d\n s/error/     /g; s/\+/ /g'; }

或者,尝试:

cleanup() { sed -e '1,5d' -e '$d' -e's/error/     /g' -e 's/\+/ /g'; }

只需用双引号将整个命令括起来就可以了,要执行存储的变量,请使用 eval:

cleanup="sed 's/error/ /g' | sed 's/\+/ /g' | tail -n +6 | ghead -n -1"
eval $cleanup

通常在 bash 中不需要在双引号字符串中转义单引号,反之亦然。

你可以这样做:

cleanup="`cat << EOF
sed 's/error/     /g' | sed 's/\+/ /g' | tail -n +6 | ghead -n -1
EOF`"

有了这个,你可以在两个 EOF 之间放置任何文本,它不会被 bash

解释
seq 8 | eval $cleanup