繁体   English   中英

使用sed或脚本解析,重新格式化日志文件?

[英]Parsing, reformating log file using sed or perhaps a script?

我有一个案子,我需要对其进行post-process 示例格式如下:-

bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
1.1.1.1 Intel::DOMAIN   from http://abcd.com/bl/BOOT via intel.criticalstack.com     F

预期产量为:-

1.1.1.1 abcd

解析为:

  • 任何不以IP地址开头的内容都会删除该行
  • 如果以IP地址开头

    • 删除Intel :: DOMAIN
    • fromF之间根据以下字符串出现情况替换它
    • 例如malc0de或abcd

我想使用sed,但我不知道如果sed可以用于匹配多个字符串(例如malc0de或abc),也许我需要一个更完整的脚本,然后只需将一个字符串存储在数组中即可。 任何想法? 顺便说一下,使用sed示例非常受欢迎。

至今

  • 我知道在sed中使用d可以删除行并将输出重定向到文件
  • 我知道如何为非IP地址匹配正则表达式[^ a-zA-Z]
  • 我被困在基于多种选择或字符串的替换中
 \\#!/bin/bash sed -is/\\[a-zA-Z]\\/d test ./infile > testme.txt sed -is/\\([0-9]\\{1,3\\}\\.\\)\\{3\\}[0-9]\\{1,3\\}/s+\\Intel::DOMAIN\\\\s*from(.*?)\\s+F\\1malc0de 

或者我正在考虑像ARRAY =(malc0de abcd)进行保存

然后代替捕获组,我可以执行$ {ARRAY [2]}呢?或者我可以执行诸如fromF之间的.net子字符串匹配的操作,将结果复制到字符串变量中。 然后搜索它以查找我的字符串,例如malc0de,如果find用匹配的结果替换了搜索到的模式? 但我不知道bash ...

用awk脚本更新我很干净

 1.1.1.1 www.abc.com 1.1.2.2 def.com 2.2.2.2 mnx.dbc.net 

但是,我希望将ip地址后的第二列缩短为我自己选择的字符串,例如,在第二列中,我只接受

abc def mnx

一次,发现它只是将整个字符串替换为

1.1.1.1 abc
1.1.2.2 def
2.2.2.2 mnx

谢谢。

您提到了sed解决方案是最受欢迎的,但是我相信awk对于您的特定任务将最易于使用。 这是我的解决方案:

awk '/^[[:digit:]]\.[[:digit:]]\.[[:digit:]]\.[[:digit:]]/ { printf $1; gsub (/http\:\/\//," "); gsub(/\.com/," ");printf " "$4"\n"  }' inputFile.txt

这个想法很简单:默认情况下, awk字段分隔符为空格,并允许打印特定的字段,因此,我们首先匹配以ip地址开头的行(四个数字点交替的模式); 我们先打印字段,然后除去https.com部分,剩下的唯一的域名就是域名4,然后我们进行打印。 其余未指定要打印,因此被忽略。

如果要编辑原始文件,则awk会有一个怪癖,那就是它不能进行内联编辑,除非这是gawk (GNU awk),因此请使用temp文件。

演示:

我的输入文件

xieerqi:$ cat inputFile.txt                                               
bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
1.1.1.1 Intel::DOMAIN   from http://abcd.com/bl/BOOT via intel.criticalstack.com     F

whatever.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
2.2.2.2 Intel::DOMAIN   from http://asdf.com/bl/BOOT via intel.criticalstack.com     F

使用临时文件传输的命令(请注意,我的inputFile.txt位于我的主目录中,请相应地调整该部分)。 注意:始终总是备份原始文件,以防万一! 或在&&之前运行命令的第一部分,检查临时文件,如果喜欢,请将文件分类为原始文件。

awk '/^[[:digit:]]\.[[:digit:]]\.[[:digit:]]\.[[:digit:]]/ { printf $1; gsub (/http\:\/\//," "); gsub(/\.com/," ");printf " "$4"\n"  }' inputFile.txt > /tmp/temp.txt && cat /tmp/temp.txt > $HOME/inputFile.txt

命令执行后的输出:

xieerqi:$ awk '/^[[:digit:]]\.[[:digit:]]\.[[:digit:]]\.[[:digit:]]/ { printf $1; gsub (/http\:\/\//," "); gsub(/\.com/," ");printf " "$4"\n"  }' inputFile.txt > /tmp/temp.txt && cat /tmp/temp.txt > $HOME/inputFile.txt


xieerqi:$ cat inputFile.txt                                                                                                                           
1.1.1.1 abcd
2.2.2.2 asdf

通过脚本简化

可以将以上命令放入具有以下内容的脚本中:

#!/usr/bin/awk -f

/^[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*/ { 
printf $1; 

gsub (/http\:\/\//," "); 
gsub (/https\:\/\//," "); 
gsub(/\.com/," ");
printf " "$4"\n";
}

请注意,在脚本中,我考虑了IP地址中多个数字的可能性以及地址中https可能性。

切记使用chmod 755 /path/to/script使脚本可执行

这是演示:

xieerqi:$ chmod 755 ipanddomain.awk                                                                                                                   

xieerqi:$ cat inputFile.txt                                                                                                                           
bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
1.1.1.1 Intel::DOMAIN   from http://abcd.com/bl/BOOT via intel.criticalstack.com     F

whatever.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
192.168.0.2 Intel::DOMAIN   from https://asdf.foobar.whatever.com/bl/BOOT via intel.criticalstack.com     F

xieerqi:$ ./ipanddomain.awk inputFile.txt                                                                                                             
1.1.1.1 abcd
192.168.0.2 asdf.foobar.whatever

要编辑原始文件,请使用带有重定向到临时文件的技巧,然后像我之前向您展示的那样还原到原始文件

编辑#2

因此,您问过:您可以简单地匹配您刚刚知道的将要打印的部分域名。 我已经对脚本进行了一些编辑。 基本上,此版本在$ 4字段中查找模式,如果找到它,它将显示“确定,该字符串中包含abcd,所以我只打印它”

#!/usr/bin/gawk -f

/^[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*\.[[:digit:]]*/ { 
printf $1" ";
matchDomain($4);
}

function matchDomain(str){

if (str~/foobar/)
 printf "foobar\n";
if(str~/abcd/)
 printf "abcd\n"

}

试试这个小家伙:

sed -nE 's/(^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}) .* [htpsw:\/.]{4,8}([0-9a-z.]+)\.com.*$/\1 \2/p' > newfile

想法是使用分组() ,定义适当的组,而不是仅使用\\1 \\2等用组替换匹配的行。- -np组合用于仅显示替换的行,并且仅在匹配模式时才替换行。 如果还要保持不匹配的行,请删除-np

输入文件:

bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
1.1.1.1 Intel::DOMAIN   from http://abcd.com/bl/BOOT via intel.criticalstack.com     F
bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
123.1.1.1 Intel::DOMAIN   from http://abcd12.bcd.com/bl/BOOT via intel.criticalstack.com     F
bigspeedpro.com Intel::DOMAIN   from https://malc0de.com/bl/BOOT via intel.criticalstack.com     F
87.1.4.1 Intel::DOMAIN   from http://abcdtdd.com/bl/BOOT via intel.criticalstack.com     F
bigspeedpro.com Intel::DOMAIN   from http://malc0de.com/bl/BOOT via intel.criticalstack.com     F
192.168.1.1 Intel::DOMAIN   from www.abcdbc12a.bdf12.com/bl/BOOT via intel.criticalstack.com     F

输出新文件:

1.1.1.1 abcd
123.1.1.1 abcd12.bcd
87.1.4.1 abcdtdd
192.168.1.1 abcdbc12a.bdf12

更新:我更新了答案,更改了sed一点,现在它可以处理http/https/www并返回https/https/www.com 而且它仍然相对较短。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM