删除模式的两个内容之间的所有新行'\ n',将它们组合成一个句子。使用sed或awk

时间:2018-04-01 08:13:47

标签: awk sed

我将此输入文件作为input.txt,如下所示 在输出中 我试图删除模式'------'的所有出现之间的所有新行。 然后从输出文件中删除该模式 print_me(0034 bla bla bla bla bla bla bla bla bla。) 并插入一个包含该数字的字符串的新行,例如 打印机名称( '0034')

input.txt中

print_me 0034 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0035 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0037 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0038 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------

所需的output.txt

    printername('0034')
    print_me(0034 bla bla bla bla bla bla bla bla bla.)
    printername('0035')
    print_me(0035 bla bla bla bla bla bla bla bla bla.)
    printername('0036')
    print_me(0036 bla bla bla bla bla bla bla bla bla.)
    printername('0037')
    print_me(0037 bla bla bla bla bla bla bla bla bla.)
    printername('0038')
    print_me(0038 bla bla bla bla bla bla bla bla bla.)

我实现answer1的输出如下:

printername('0034')
print_me(0034 bla bla bla bla b  la bla bla bla bla.   )
printername('0035')
print_me(0035 bla bla bla bla b  la bla bla bla bla.   )
printername('0036')
print_me(0036 bla bla bla bla b  la bla bla bla bla.   )
printername('0037')
print_me(0037 bla bla bla bla b  la bla bla bla bla.   )
printername('0038')
print_me(0038 bla bla bla bla b  la bla bla bla bla.   )

所以现在我如何改进代码以删除额外的标签并在模式之间组合任意数量的行,并将它们作为print_me括号内的一个句子读取(bla bla bla bla + bla = bla +/- bla ) - 例子

input2.txt

print_me 0034 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0035 bla bla bla bla bl
              a bla bla bla bla-
              a bla bla bla bla.
------ -------------------------
print_me 0037 bla bla bla__la bl
              a bla bla bla bla
              bla b bla a_% bla+
              a bla bla bla bla.
------ -------------------------
print_me 0038 bla bla+bla= bla l
              a bla bla +/-blala.
              a bla bla bla blah
              _bla bla bla blaa
              a bla bla bla blaa
              a bla bla bla bla.
------ -------------------------

4 个答案:

答案 0 :(得分:0)

编辑: 根据OP,-与实际的行之间可能有多行,因此在代码之后打印所有这些行可能会有所帮助。 假设以下是示例Input_file:

cat Input_file
print_me 0034 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0035 bla bla bla bla bl
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
              a bla bla bla bla.
------ -------------------------
print_me 0037 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------
print_me 0038 bla bla bla bla bl
              a bla bla bla bla.
------ -------------------------

接下来是可能对此有帮助的代码。

awk '/print_me/{print "printername(\047" $2 "\047)";val=$0;sub(/ /,"(",val);getline;while($0!~/^-/){sub(/ +/,"");value=value?value $0:$0;getline};print val value")";val=value=""}'  Input_file

此处也添加非单线形式的解决方案。

awk '
/print_me/{
  print "printername(\047" $2 "\047)";
  val=$0;
  sub(/ /,"(",val);
  getline;
  while($0!~/^-/){
     sub(/ +/,"");
     value=value?value $0:$0;
     getline};
  print val value")";
  val=value=""
}
'  Input_file

关注awk可能对您有所帮助。根据您显示的示例,您认为在--行之后只有1行加入。

awk '/print_me/{print "printername(\047" $2 "\047)";val=$0;sub(/ /,"(",val);getline;sub(/ +/,"");print val $0")"}'  Input_file

现在也添加非单线形式的解决方案。

awk '
/print_me/{
  print "printername(\047" $2 "\047)";
  val=$0;
  sub(/ /,"(",val);
  getline;
  sub(/ +/,"");
  print val $0")"
}
'   Input_file

答案 1 :(得分:0)

使用GNU awk进行多字符RS(以及\s\S分别为[[:space:]][^[:space:]]的简写,因为我们正在使用gawk反正):

$ awk -v RS='\n[- ]+\n' '
{
    cmd = $1
    sub(/\S+\s+/,"")
    gsub(/\n\s*/,"")
    printf "printername(\047%s\047)\n%s(%s)\n", $1, cmd, $0
}
' input.txt
printername('0034')
print_me(0034 bla bla bla bla bla bla bla bla bla.)
printername('0035')
print_me(0035 bla bla bla bla bla bla bla bla bla.)
printername('0037')
print_me(0037 bla bla bla bla bla bla bla bla bla.)
printername('0038')
print_me(0038 bla bla bla bla bla bla bla bla bla.)

其他问题是:

$ awk '
/^[- ]+$/ {
    $0 = rec
    cmd = $1
    sub(/[^[:space:]]+[[:space:]]+/,"")
    gsub(/\n[[:space:]]*/,"");
    printf "printername(\047%s\047)\n%s(%s)\n", $1, cmd, $0
    rec = ""
    next
}
{ rec = rec $0 ORS }
' input.txt

请注意,上面测试的唯一输入值是针对每条记录(---...)末尾出现的破折号线。它不会测试print_me或每条记录中出现的任何其他文字,因此如果您在输入中有print_me以外的其他说明,它仍然会按原样运行。

答案 2 :(得分:0)

如果您的输入是常规的,那么它只有3行awk:

awk -v q="'" '
    /^-+/ {print ")"; next}
    /^print_me/ {print "printername(" q $2 q ")"; sub(/ /, "(")}
    { gsub(/^[[:blank:]]+/, ""); printf "%s", $0 }
' input2.txt

输出

printername('0034')
print_me(0034 bla bla bla bla bla bla bla bla bla.)
printername('0035')
print_me(0035 bla bla bla bla bla bla bla bla bla-a bla bla bla bla.)
printername('0037')
print_me(0037 bla bla bla__la bla bla bla bla blabla b bla a_% bla+a bla bla bla bla.)
printername('0038')
print_me(0038 bla bla+bla= bla la bla bla +/-blala.a bla bla bla blah_bla bla bla blaaa bla bla bla blaaa bla bla bla bla.)

答案 3 :(得分:0)

使用gnu sed

sed -E '
  h
  s/([^ ]*) ([^ ]*).*/printername\('"'"'\2'"'"'\)/
  x
  :A
  /\n[- ]+$/bB
  N
  bA
  :B
  s//)/
  y/\n/ /
  s/[[:blank:]][[:blank:]]+/ /g
  s/ /(/
  x
  G
' input2.txt