【问题标题】:Print the consecutive 3 line at the pattern match在模式匹配处打印连续的 3 行
【发布时间】:2016-08-08 08:08:24
【问题描述】:

我有一个巨大的文件,我需要对模式匹配“vm”的 3 行进行排序和合并,并将它们合并到单行中,如下所示

kfg-ap4 是服务器名称,我们只能拥有它一次,在排序时会很好.. 我用 getline 尝试了 awk,但不知何故我想不适合它..

awk '/vm/ {printf $0 " ";getline;打印 $0}' mem_overc

**[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0**


[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:

================================================ ========================

实际数据如下,除服务器名称外其余数据相同

[kfg-ap3] Executing task 'moc'
[kfg-ap3] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap3] out:
[kfg-ap3] out: We trust you have received the usual lecture from the local System
[kfg-ap3] out: Administrator. It usually boils down to these three things:
[kfg-ap3] out:
[kfg-ap3] out:     #1) Respect the privacy of others.
[kfg-ap3] out:     #2) Think before you type.
[kfg-ap3] out:     #3) With great power comes great responsibility.
[kfg-ap3] out:
[kfg-ap3] out: sudo password:
[kfg-ap3] out: vm.overcommit_memory = 0
[kfg-ap3] out: vm.overcommit_ratio = 50
[kfg-ap3] out: vm.nr_overcommit_hugepages = 0
[kfg-ap3] out:

[kfg-ap4] Executing task 'moc'
[kfg-ap4] sudo: /sbin/sysctl -A | grep overcommit
[kfg-ap4] out:
[kfg-ap4] out: We trust you have received the usual lecture from the local System
[kfg-ap4] out: Administrator. It usually boils down to these three things:
[kfg-ap4] out:
[kfg-ap4] out:     #1) Respect the privacy of others.
[kfg-ap4] out:     #2) Think before you type.
[kfg-ap4] out:     #3) With great power comes great responsibility.
[kfg-ap4] out:
[kfg-ap4] out: sudo password:
[kfg-ap4] out: vm.overcommit_memory = 0
[kfg-ap4] out: vm.overcommit_ratio = 50
[kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out:

【问题讨论】:

  • 什么是 Python 问题?
  • @Trimax .. 很抱歉造成混乱,我正在尝试使用 awk、sed、python 来解决这个问题。python 没有问题
  • 实际数据和预期结果是哪一部分?
  • @James .. 具有“[kfg-ap4]”服务器名称的整个集合是我们需要对其进行排序的数据的实际部分。
  • 好的,你只高亮了你想打印的行。谢谢。

标签: python awk sed


【解决方案1】:

你快到了:只需在变量中累积并最终打印:

awk 'BEGIN{s="";} /vm/ {s = s $0 " "} END {print s}' log.txt

您还可以使用您的确切构造并转换换行符:

awk '/vm/ {printf $0 " ";getline; print $0}' log.txt | tr "\n" " "

【讨论】:

  • ..上面的代码将所有 log.txt 数据放入一行,当模式匹配时我需要获取每三行并将其缩小到文件末尾..所以,3行合二为一,依此类推...
  • 你的意思是3行是连续的,那么
【解决方案2】:
$ awk '/vm/ {printf "%s%s", $0, (++i%3?OFS:ORS)}' log.txt
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0
[kfg-ap4] out: vm.overcommit_memory = 0 [kfg-ap4] out: vm.overcommit_ratio = 50 [kfg-ap4] out: vm.nr_overcommit_hugepages = 0

步行:

/vm/ {                                 # if vm on the record
    printf "%s%s", $0, (++i%3?OFS:ORS) # print record and OFS
}                                      # every 3rd time print ORS

因为实际上一组中有超过 3 行,所以使用这个:

$ awk '/vm/ {buf=buf OFS $0; next} buf!="" {print buf; buf=""}'

它会缓冲记录并在遇到与/vm/ 不匹配的记录后将其打印出来。如果您的文件中有连续的组,则可能会出现问题。您最终可能会得到比预期更长的行。

$ cat > process.awk
/vm/ {              # if vm string in the record
    buf=buf OFS $0  # append the record $0 to the buffer variable buf
    next            # skip the rest of script for this record, ie.
}                   # only records without vm match get past this point
buf!="" {           # if the buffer is not empty
    print buf       # print it out
    buf=""          # empty the buffer
}
$ awk -f process.awk log.txt

【讨论】:

  • 你能发布一些实际数据,特别是有问题的部分吗?
  • 好吧,根据您发布的数据,我得到 2 行作为输出,两行都有 3 条 vm 记录。
  • 是的,我可以看到,太好了,我可以在此处附上数据文件以查看更多信息.. 谢谢。
  • 将其放入 Pastebin 并发布 URL。
  • 有些组有超过 3 个连续的vm 记录。在我的回答中查看另一个版本。
【解决方案3】:

仅使用sed 的另一个答案

/vm/{
H
x
s/\n/ /g
s/ \[kfg-ap.\] out: / /
x
blab
}
x
p
:lab

像这样调用(将上面的文件保存为filter.sed):

sed -n -f filter.sed text.txt 

如果vm 匹配,则存储在保持缓冲区中。然后交换整个缓冲区以删除行中的换行符和无用的 kfg 前缀,再次交换。

如果不匹配,再次交换缓冲区并打印。

相当简单且效果很好(极端情况:如果日志以 vm 行结尾,则可以省略它们)

【讨论】:

  • 感谢 Jean 的输入,这段代码部分工作,因为它连接了预期的行,但同时它也产生了日志文件的其他输出。我们只需要匹配 /vm 的行/,谢谢。
  • 好的,这只是为了好玩sed,我没有完全理解你的问题。由于接受了一个答案,除非您坚持使用神秘的sed,否则我不会进一步挖掘
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-27
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-16
相关资源
最近更新 更多