让我说我有来自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
答案 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中捕获所需的位,然后打印它们。