如何在SED中的行范围内用冒号替换换行符

时间:2013-12-11 12:38:43

标签: sed awk

我想在以start开头并以End结尾的行之间的文件中搜索行范围,并用冒号替换换行符。我需要在SED或AWK中完成。

示例文件:

start
a
b
c
End
Start
a
b
c
End
Start
x
y
z
End

预期产出:

a:b:c
a:b:c
x:y:z

6 个答案:

答案 0 :(得分:4)

这个简短的单行应该可以工作:

 awk -v RS='Start|End' -v OFS=":" '$1=$1' file

包含您的数据:

kent$  cat f
Start
a
b
c
End
Start
a
b
c
End
Start
x
y
z
End

kent$  awk -v RS='Start|End' -v OFS=":" '$1=$1' f
a:b:c
a:b:c
x:y:z

答案 1 :(得分:1)

让我们试试awk

$ awk '/start/ || /Start/ {next} /End/ {print line; line=""; next} {if (line) {line=line":"} line=line$0}' file
a:b:c
a:b:c
x:y:z

解释

  • /start/ || /Start/ {next}在包含“开始”或“开始”的行上,跳过。
  • 在包含/End/ {print line; line=""; next}的行上
  • End,打印包含已加载信息的line变量。删除var的值并转到下一行。
  • 其余行
  • {if (line) {line=line":"} line=line$0},继续在line变量中加载数据。 if条件是避免使用尾随:

/start/ || /Start/ {next}可以缩减为这两种(thanks Jotne):

/start|Start/ {next}

/(s|S)tart/ {next}

答案 2 :(得分:1)

这是一个版本:

awk '/End/{print a;f=a=0} f {a=a?a":"$0:$0} /(S|s)tart/{f=1}' file
a:b:c
a:b:c
x:y:z

我猜第一个start中有拼写错误,如果是这样,请使用:

awk '/End/{print a;f=a=0} f {a=a?a":"$0:$0} /Start/{f=1}' file

/End/{print a;f=a=0}如果行包含End打印a,则将fa设置为0
f {a=a?a":"$0:$0}如果f为真,请先将a设为$0进行首次运行,然后在下次运行时设为:$0 /Start/{f=1}如果行Startf设置为1(true)

答案 3 :(得分:1)

如果开始和结束之间总是有3行:

grep -iv 'start\|end' file | paste -d: - - -

答案 4 :(得分:0)

sed -n '/Start/,/End/ {
   /Start/ !{
      /End/ !H
      }
   /End/ {
      s/.*//
      x
      s/\n/:/g
      s/://
      p
      }
   }
/Start/,/End/ !p' YourFile

如果 start Start应该工作,请Start替换[sS]tartEnd[eE]nd)在代码中

<强>释

除非特定请求

,否则请先打开sed而不打印ouptut
/Start/,/End/ {

对于以Start开头且以End结尾的任何行块(在单独的行上)

/Start/ !{
          /End/ !H
          }

如果行不包含(!Start而不是End,则将该行添加(追加)到保留缓冲区(存储类型)

/End/ {
   s/.*//
   x
   s/\n/:/g
   s/://
   p
   }

到达包含End

的行
  1. 删除当前行(End
  2. 交换(x)保持缓冲区(存储了所有行的行)和工作缓冲区(可以操作且通常具有当前行的缓冲区)
  3. :更改所有新行(缓冲区包含交换后新行分隔的所有行)
  4. 首先删除:(由于第一个附加插入新行)
  5. 打印内容

    /开始/,/结束/!p

  6. 对于!Start之间的块之间的所有行(End),请将其打印

答案 5 :(得分:0)

使用GNU awk的另一种方法:

$ gawk -v RS='\0' '{ gsub(/\n/,":"); gsub(/:End:Start:/,"\n"); gsub(/^start:|:End:$/,"") }1' file     
a:b:c
a:b:c
x:y:z

此处发布的其他awk解决方案也很好。