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

时间:2015-08-07 08:30:47

标签: bash sed escaping quoting

我使用以下管道来处理一些文本:

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。但是,我仍然对比我更优雅的方法感兴趣。

3 个答案:

答案 0 :(得分:4)

如果清理是一个函数,而不是字符串,它将起作用:

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删除第1行至第5行。这将取代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'; }

答案 1 :(得分:1)

使用双引号围绕整个命令应该有效,执行存储的变量使用eval:

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

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

答案 2 :(得分:0)

您可以这样做:

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

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

seq 8 | eval $cleanup