Bash 使用awk和解析变量逐行读取
我有一个脚本,可以读取日志文件并解析数据以将其插入mysql表。Bash 使用awk和解析变量逐行读取,bash,parsing,awk,while-loop,line,Bash,Parsing,Awk,While Loop,Line,我有一个脚本,可以读取日志文件并解析数据以将其插入mysql表。 我的脚本看起来像 while read x;do var=$(echo ${x}|cut -d+ -f1) var2=$(echo ${x}|cut -d_ -f3) ... echo "$var,$var2,.." >> mysql.infile done<logfile 如果您认为perl会更好,我愿意听取建议,也许可以给您一个如何编写脚本的提示……下面的perl脚本可能会有所帮助: perl -ane
我的脚本看起来像
while read x;do
var=$(echo ${x}|cut -d+ -f1)
var2=$(echo ${x}|cut -d_ -f3)
...
echo "$var,$var2,.." >> mysql.infile
done<logfile
如果您认为
perl
会更好,我愿意听取建议,也许可以给您一个如何编写脚本的提示……下面的perl脚本可能会有所帮助:
perl -ane '/^[^+]*/;printf "%s,",$&;/^([^_]*_){2}([^_]*){1ntf "%s\n",$+' logfile
由于,$&
可能导致性能损失,因此您也可以使用/p
修饰符,如下所示:
perl -ane '/^[^+]*/p;printf "%s,",${^MATCH};/^([^_]*_){2}([^_]*){1}_.*/;printf "%s\n",$+' logfile
有关
perl
regex匹配的更多信息,请参阅如果要按顺序提取值,类似这样的内容会有所帮助
$ awk -F\" '{for(i=2;i<=NF;i+=2) print $i}' file
idle Timeout
x.x.x.x
19219
x.x.x.x
53
dns-udp
DNS
$awk-F\”{(i=2;i为了回答你的问题,我假设游戏规则如下:
- 每行包含各种变量
- 每个变量都可以通过不同的分隔符找到
这将为您提供以下awk脚本:
awk 'BEGIN{OFS=","}
{ FS="+"; $0=$0; var=$1;
FS="_"; $0=$0; var2=$3;
...
print var1,var2,... >> "mysql.infile"
}' logfile
其基本功能如下:
- 将输出分隔符设置为
,
- 读线
- 将字段分隔符设置为
+
,重新分析行($0=$0
)并确定第一个变量
- 将字段分隔符设置为“u”,重新分析该行(
$0=$0
)并确定第二个变量
- …对所有变量继续
- 将该行打印到输出文件
我认为awk
不会在时间上给您带来任何显著的改进。请使用另一种语言。对于长任务,我已经用Perl替换了几次bash脚本,差别很大。Shell很慢。@sjsam为什么不呢?请参阅@Vesser,如果您添加一个示例输入(比如3-5行),它会有所帮助并显示您需要附加到另一个文件的预期输出…无需复制您的完整需求,将其限制为3variables@Sundeep:请注意,我在评论中使用了重要的
。对于较大的文件,建议使用perl
。此外,您指出的链接实际上没有对工具进行比较。它只是讨论了实践的起伏。这很好,我几乎完成了,我面临的唯一问题是我需要解析来自geoiplookup ipaddress的变量,现在我尝试了awk-v country=“$country”和FS=“\”;$0=$0;CIP=$4;但是如何通知每行执行country=$(geoiplookup CIP)我得到了一个语法错误好的,我在很高兴看到你找到了解决方案。如果你使用getline
并且你有很多相同的CIP
值,缓冲结果以加速编程可能会很有用。有很多相同的值,我应该如何缓冲结果…?这取决于你在做什么,但是您可以使用以下awk行(buffer[CIP]==0){cmd=“geoiiplookup”CIP;cmd | getline buffer[CIP];close(cmd)}
。这将缓冲结果,即将其存储在数组中。如果该值已经存在,则不再执行geoiiplookup
,而只需从buffer[CIP]
$ awk -F\" -v OFS=, '{for(i=2;i<=NF;i+=2)
printf "%s", $i ((i>NF-2)?ORS:OFS)}' file
idle Timeout,x.x.x.x,19219,x.x.x.x,53,dns-udp,DNS
awk 'BEGIN{OFS=","}
{ FS="+"; $0=$0; var=$1;
FS="_"; $0=$0; var2=$3;
...
print var1,var2,... >> "mysql.infile"
}' logfile