Sed命令仅在分为两个步骤时才有效

时间:2016-06-01 20:35:00

标签: command-line sed

有人可以向我解释为什么将第1步和第2步合并为一个sed命令并不起作用:

sed -e :a -e 's/^.\{0,127\}$/& /;ta' \
-e '1,46d' -e '/Pharmacom/,+5d' -e 's/^M//g' \
-e ':a;N;$!ba;s/\n//g' -e 's/---*/\n/g' file > result

但同样的命令分为两步:

第1步:

sed -e :a -e 's/^.\{0,127\}$/& /;ta' -e '1,46d' \
-e '/Pharmacom/,+5d' -e 's/^M//g'  FILE > step

第2步:

sed -e ':a;N;$!ba;s/\n//g' -e 's/---*/\n/g' step > result

1 个答案:

答案 0 :(得分:2)

我首先将你的命令翻译成可读的东西,这样我才能理解它:

# Pad lines with spaces until 128 characters long
:a
s/^.\{0,127\}$/& /
ta

# Delete first 46 lines
1,46d

# Delete line containing 'Pharmacom' and next five lines
/Pharmacom/,+5d

# Remove carriage returns
s/^M//g

# Join rest of lines on single line
:a
N
$!ba
s/\n//g

# Replace two or more dashes with a newline
s/---*/\n/g

然后我把它缩小到有问题的部分:

# Pad lines with spaces until 128 characters long
:a
s/^.\{0,127\}$/& /
ta

# Join rest of lines on single line
:a
N
$!ba
s/\n//g

或者,在一条线上:

sed ':a;s/^.\{0,127\}$/& /;ta;:a;N;$!ba;s/\n//g'

问题是你使用相同的标签名称两次,所以s命令跳转到第二个标签{{1},而不是重复你的第一个ta命令。而不是填充到128个字符,只需插入一个空格。

使用两个不同的标签名称可以很容易地解决这个问题:

:a

两个评论:

  • 如果您在此上下文中使用sed ':a;s/^.\{0,127\}$/& /;ta;:b;N;$!bb;s/\n//g' sed -e '...' -e '...',则无关紧要;它们都算作单个命令,标签名称必须是唯一的。
  • 我将sed '...;...'命令移动到脚本的开头,或者您在所删除的行上完成所有填充工作。