用sed替换从stdin读取的奇数行

时间:2016-01-06 19:46:30

标签: bash sed

作为考试准备,我和朋友决定用sed玩一下。然而,我们在尝试在奇数行上执行子行时发现了一些奇怪/异常的行为。

看起来像所有sed命令但是p命令在处理来自stdin的输入时不起作用

示例:https://gyazo.com/1c8d7fcb2ebd992849704b80c8ec6ab9

Direct image

echo -e "1\n2\n3\n4\n5" | sed -n '1~2p' # Works fine / as expected
echo -e "1\n2\n3\n4\n5" | sed -n '1~2s/./&&/g' # Doesn't give output. The specific substitution is just a test.
echo -e "1\n2\n3\n4\n5" | sed -n '1~2d' # Once again no output. (I'm aware that this is equal to only printing the even lines.) 

这种行为有理由吗?

我们确实在此期间弄清楚了,但是,似乎

sed 'N;s/./&&/g' 

确实会奏效。

虽然问题仍然存在:如果我只想在第50行进行替换怎么办?我不想写N; N; N; ...在应用替换之前50次。

3 个答案:

答案 0 :(得分:3)

你快到了。您遇到的问题是您正在使用-n禁止自动打印模式空间),但您不能告诉sed以任何方式打印行

为防止出现这种情况,您可以压缩-n并以不同方式处理条件,也可以添加-p来触发打印。

查看案例:

sed -n '1~2d'因为您使用-n停止打印而无法打印任何内容,因此您需要告诉sed"嘿,打印一些内容"。

所以你可以说删除奇数行:

$ echo -e "1\n2\n3\n4\n5" | sed '1~2d'
2
4

或删除后添加p

$ echo -e "1\n2\n3\n4\n5" | sed -n '1~2d;p'
2
4

这同样适用于第二个命令:如果你在替换后添加p,它就可以了!

$ echo -e "1\n2\n3\n4\n5" | sed -n '1~2s/./&&/gp'
11
33
55
  

虽然问题仍然存在:如果我只想表演,该怎么办?   替换在第50行?我不想写N; N; N;   ...在应用替换之前50次。

为此我会使用awk

awk 'NR==50 {things...}' file

这使用记录行号的变量NR来跟踪行号。

答案 1 :(得分:0)

  

如果我只想在第50行进行替换怎么办?

您可能需要阅读有关地址部分的sed手册页。

检查此seq 10|sed '7s/.*/-/'

顺便说一下,你的N;N;...50times错了。这将在前50行而不是第50行进行替换。你可以通过一些测试来弄明白。

答案 2 :(得分:0)

回答略有不同,但仍适用于OSX(例如编辑原始文件的第4行):

seq 1 8  | sed -e '1d;4s/./&&/g;n;d'

或编辑所有偶数行:

seq 1 8  | sed -e '1d;s/./&&/g;n;d'

或编辑所有奇数行(未询问,但以防万一有人会在将来发现它有用):

seq 1 8  | sed -e 's/./&&/g;n;d'

sed的有用提示: 1d - 删除第一行 n - 用下一行替换该行 d - 删除下一行并再次开始循环(替换和删除)。