示例:
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模式是信息性的
答案 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