通过sed

时间:2016-04-15 05:44:25

标签: bash sed pipe conditional

有没有办法在bash脚本中通过sed有条件地管理命令的输出?根据脚本选项,我要么想通过sed管道长管道的输出,要么通过sed省略管道。目前我在做

if [ $pipeit ]; then
   sed_args='/omit this line/d'
else
   sed_args='/$^/d'  # pass-thru (what's a better sed pass thru?)
fi

some_cmd | sed "$sed_args"

2 个答案:

答案 0 :(得分:3)

我会保持简单:

if [ $pipeit ]; then
   some_cmd | sed '/omit this line/d'
else
   some_cmd
fi

如果您不需要,为什么要拨打sed?仅为了您的信息,一个不会改变输入的sed命令是sed -n p

顺便说一句,如果some_cmd是一种大型野兽而你想避免重复它,请将其包装成一个函数。

答案 1 :(得分:1)

默认情况下sed会打印所有行:

if [ $pipeit ]; then
  sed_args='/omit this line/d'
else
  sed_args=""  # pass-thru
fi

some_cmd | sed "${sed_args}"

还有其他经过测试的解决方案:

some_cmd | if [ $pipeit ]; then
  sed "/omit this line/d"
else 
  sed ""
fi
可以使用

cat代替sed ""

最后,可以使用eval构建和执行字符串。

some_cmd='printf "foo\n\nbar\n"'
if [ $pipeit ]; then
  conditional_pipe='| sed "/foo/d"'
else
  conditional_pipe=""
fi

eval "${some_cmd}" "${conditional_pipe}"

如果some_cmd很复杂,那么使用eval构建一个符合预期效果的字符串就很难进行迁移。

----

历史的第一个解决方案

使用sed的不可能匹配将使所有行打印到stdout:

$ printf "foo\n\nbar\n" | sed "/./{/^$/d}"
foo

bar

/./选择至少包含一个字符的行。 /^$/选择一个空行。