如何在多个调用的变量中保存 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
我使用以下管道对某些文本进行后处理:
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