使用`sed`多次没有管道

时间:2011-12-11 16:43:02

标签: sed

示例:

echo one two three | sed 's/ /\n/g' | sed 's/^/:/g'

输出:

  

:一个
  :二
  :3

没有管道:

echo one two three | sed 's/ /\n/g;s/^/:/g'

输出:

  

:一个
  2个
  3

似乎第一个模式在执行第二个模式之前没有扩展,但我真的不太了解sed

如何在没有管道两次的情况下使用第一个示例?

示例中使用的PS模式是信息性的

4 个答案:

答案 0 :(得分:8)

另一种方法是使用重复的-e选项:

echo one two three | sed -e 's/ /\n:/g' -e 's/^/:/g'

当您有许多操作要做时,这更容易理解;您可以在单独的行上对齐单独的操作:

echo one two three |
sed -e 's/ /\n:/g' \
    -e 's/^/:/g'

例如,我有一个脚本可以从模板生成大纲文档。脚本的一部分包含:

sed -e "s/[:]YEAR:/$(date +%Y)/g" \
    -e "s/[:]TODAY:/$today/" \
    -e "s/[:]BASE:/$BASE/g" \
    -e "s/[:]base:/$base/g" \
    -e "s/[:]FILE:/$FILE/g" \
    -e "s/[:]file:/$file/g" \
    $skeleton |
...

虽然可以在一行上完成,但它不会提高可读性。

答案 1 :(得分:1)

这里的主要问题是sed在执行任何命令之前决定构成一条线(它工作的模式)的构成。也就是说,如果您只有一个模式(one two three),则在执行s/ /\n/g后不会将其重新解释为多行。如果仍然是单个模式,尽管那将是包含其内部换行符的模式。

在新插入的换行符中使sed重新解释模式的最简单的解决方法就是像你一样运行sed两次。

另一种解决方法是将m选项(多行缓冲区)添加到s命令:

$ echo one two three | sed 's/ /\n/g;s/^/:/mg'
:one
:two
:three

答案 2 :(得分:1)

您可以将所有内容放入一个正则表达式中,如下所示:

echo one two three | sed 's/\([^ ]\+\)\( \+\|$\)/:\1\n/g'

第一部分\([^ ]\+\)选择你的单词(即一个不是空格的字符串。秒部分\( \+\|$\)匹配一个或多个空格或行结尾(这是必需的) three之后没有空格。

然后我们通过使用对第1部分中匹配的单词的反向引用来构建该行。

答案 3 :(得分:0)

这可能对您有用:

echo one two three | sed 'y/ /\n/;s/^/:/mg'
:one
:two
:three