如果下一行不匹配,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()
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()