如果下一行不匹配,awk 删除 \n

awk remove \n if next line doesn't match

awk 'tolower([=10=]) ~ /\.[log(message|event)|trace(error)?c?|infoc?|warnc?|debugc?|errorc?]/,/)/{gsub(/^\t+/, "", [=10=]);print NR","[=10=]}' example_file

我创建了这个脚本,它在一个文件中找到如下模式:

log.Info("hello world")
log.Error()

并输出如下内容:

4,log.Info("hello world")
7,log.Error()

行号和文本本身。

问题是,如果我的文件中有这样的内容:

log.Info("hello world")
log.Warn(
    "hello world")
log.Error()

它会输出这样的东西:

4,log.Info("hello world")
5,log.Warn(
6,"hello world")
7,log.Error()

我想使 "hello world")log.Warn( 在同一行。

如果找到的下一行不是以模式 /\.[log(message|event)|trace(error)?c?|infoc?|warnc?|debugc?|errorc?]/ 开头,它会将这一行放在之前的行上。

所需的输出类似于:

4,log.Info("hello world")
5,log.Warn("hello world")
7,log.Error()

非常感谢。

Like if the next line found doesn't start with the pattern /.[log(message|event)|trace(error)?c?|infoc?|warnc?|debugc?|errorc?]/ it will put this line on the line before that.

不能依赖下一行,只能依赖当前行。这基本上意味着您必须:

  • 缓冲一行(前一行)
  • 如果当前行确实以模式 /.[log(message|event)|trace(error)?c?|infoc?|warnc?|debugc?|errorc?]/ 输出前一行。上一行成为当前行。
  • 否则,输出上一行和当前行。上一行变为空。
  • END { 输出上一行 }

一些事情:

awk '
    /^log\./{  # the pattern here
       if (last) {
         print NR - 1, last;  # output previous line
        }
       last=[=10=]  # previous line becomes current line
       next
    }
    { # otherwise, because next above
       print NR - 1, last [=10=]   # output previous line and current line
       last=""  # previous line becomes empty.
    }
    END{
      if (last) {
        print NR, last  # Handle previous line on the end.
      }
    }
'

更改您的条件,使其仅取决于“当前行”。比如,如果当前行不以 ) 结尾,则吃掉下​​一行。

awk '/[^)]$/{
   n=NR
   a=[=11=]
   getline
   print n " " a [=11=]
}'

这是一个尽力而为的脚本(即在各种下雨天的情况下会失败),使用这个输入文件:

$ cat file
foo
log.Info("hello
        world")
log.Warn(
    "hello
                some other
        world")
log.Error()
bar

和任何 POSIX awk:

$ cat tst.awk
BEGIN {
    begRe = "log[.](Info|Warn|Error)[(]"
    regexp = begRe "[^)]*[)]"
    OFS = ","
}
[=11=] ~ begRe {
    begNr = NR
    buf = ""
}
begNr {
    buf = buf [=11=]
    if ( match(buf,regexp) ) {
        buf = substr(buf,RSTART,RLENGTH)
        gsub(/[[:space:]]*"[[:space:]]*/,"\"",buf)
        print begNr, buf
        begNr = 0
    }
}

$ awk -f tst.awk file
2,log.Info("hello       world")
4,log.Warn("hello               some other      world")
8,log.Error()

如果你想折叠引号内的所有白色 space 并删除任何前导白色 space 那么只需在打印语句之前添加 gsub(/[[:space:]]+/," ",buf); gsub(/^ | $/,"",buf)

$ cat tst.awk
BEGIN {
    begRe = "log[.](Info|Warn|Error)[(]"
    regexp = begRe "[^)]*[)]"
    OFS = ","
}
[=13=] ~ begRe {
    begNr = NR
    buf = ""
}
begNr {
    buf = buf [=13=]
    if ( match(buf,regexp) ) {
        buf = substr(buf,RSTART,RLENGTH)
        gsub(/[[:space:]]*"[[:space:]]*/,"\"",buf)
        gsub(/[[:space:]]+/," ",buf); gsub(/^ | $/,"",buf)
        print begNr, buf
        begNr = 0
    }
}

$ awk -f tst.awk file
2,log.Info("hello world")
4,log.Warn("hello some other world")
8,log.Error()