Linux - 用awk读取记录直到最后

时间:2015-06-10 09:20:24

标签: linux awk

让我说我有来自logfile的文本:

Jun 10 11:09:07 mylinux daemon.notice openvpn[3710]: TCPv4_CLIENT link remote: 1.22.333.444:1111

但我不需要“mylinux”和下一个冒号之间的部分: 这是我尝试删除的部分:daemon.notice openvpn[3710]

我用awk解决了它,但这不是一个好的解决方案。

awk '{print $1,$2,$3,$4,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20;}' /var/log/messages

我只是写了很多“$”来覆盖尽可能多的行,但如果有更多的行然后$ ofc,这将无效。

我知道我可以查看“NF”存在多少行,但我不知道如何使用这些信息。

日志文件中的记录如何:

Jun 10 11:47:29 FeketeLUA daemon.notice openvpn[3710]: LZO compression initialized
Jun 10 11:47:29 FeketeLUA daemon.notice openvpn[3710]: Attempting to establish TCP connection with 5.55.222.34:1122 [nonblock]
Jun 10 11:47:30 FeketeLUA daemon.notice openvpn[3710]: TCP connection established with 12.11.123.444:1111

3 个答案:

答案 0 :(得分:3)

我认为正则表达式是走到这里的方式。使用awk可以实现这一点,但使用Perl更容易:

perl -pe 's/mylinux\K.*?(?=TCPv4_CLIENT)/ /' /var/log/messages

其中

  • \K之前的所有内容都必须存在,但不会被视为匹配的一部分(后来被替换)
  • .*?非贪婪地匹配任何字符串(即,尽可能短的匹配而不是最长的匹配)
  • (?=TCPv4_CLIENT)是一个前瞻术语,匹配空字符串if(且仅当)后跟TCPv4_CLIENT

因此,正则表达式将匹配mylinux与其后的第一个TCPv4_CLIENT之间的部分,并将其替换为空格。

更新:对于已更改的问题实际上更容易,因为结尾分隔符是已删除匹配的一部分,我们不需要它的前瞻术语:

perl -pe 's/FeketeLUA\K.*?://' /var/log/messages

\K.*?继续按照之前的说法运作。

答案 1 :(得分:2)

我一定错过了一些东西,因为听起来你需要的只是:

$ sed -r 's/(mylinux)[^:]+:/\1/' file
Jun 10 11:09:07 mylinux TCPv4_CLIENT link remote: 1.22.333.444:1111

$ awk '{x="mylinux"; sub(x"[^:]+:",x)} 1' file
Jun 10 11:09:07 mylinux TCPv4_CLIENT link remote: 1.22.333.444:1111

如果您想在2分之间移除而不提及“mylinux”,那么那就是:

$ sed -r 's/(([^ ]+ +){4})[^:]+: /\1/' file
Jun 10 11:09:07 mylinux TCPv4_CLIENT link remote: 1.22.333.444:1111

$ awk '{print gensub(/(([^ ]+ +){4})[^:]+: /,"\\1","")}' file
Jun 10 11:09:07 mylinux TCPv4_CLIENT link remote: 1.22.333.444:1111

第二个awk命令使用gawk用于gensub() - 与其他awks一起使用match()+ substr()。

答案 2 :(得分:1)

Gnu awk方式

awk 'match($0,/(.*mylinux).*(TCPv4_CLIENT.*)/,a){print a[1],a[2]}' file

Jun 10 11:09:07 mylinux TCPv4_CLIENT link remote: 1.22.333.444:1111

在数组a中捕获所需的位,然后打印它们。