Awk 找到第一个匹配项后匹配特定模式,并在它们之间关联列
我需要找出文件中不共享公共标识符的两个相关行之间的时间戳差异。例如:Awk 找到第一个匹配项后匹配特定模式,并在它们之间关联列,awk,Awk,我需要找出文件中不共享公共标识符的两个相关行之间的时间戳差异。例如: 正文 2018-01-29 15:05:11592验证控制 正文 正文 正文 2018-01-29 15:05:12725完成验证控制 由于每个验证过程都没有唯一的标识符,因此我需要: 首先将一行与“正在验证控制…”匹配 将时间戳保存到数组中 匹配文件中包含“已完成验证控件”的下一行 保存时间戳 我有一个计算时间差的函数——我有一段艰难的时光 分析并关联每两个验证/已完成验证行。虽然每一行都有数百行,但它们总是按顺序出现,并按
#!/bin/bash
while read -r a b c d e; do
[[ "$c $d" =~ Validating\ control... ]] && echo "$a $b"
[[ "$c $d $e" =~ Done\ validating\ control. ]] && echo "$a $b"
done < file
#/bin/bash
而read-ra-b-c-d-e;做
[[“$c$d”=~验证\控制…]&&echo“$a$b”
[[“$c$d$e”=~Done\validating\control.]&&echo“$a$b”
完成<文件
或
#/bin/bash
而read-ra-b-c-d-e;做
[[“$c$d”=~验证\控制…]&&start=“$a$b”
如果[[“$c$d$e”=~完成\验证\控制。]];然后
stop=“$a$b”
回显“$start”
回音“$stop”
fi
完成<文件
输出:
2018-01-29 15:05:11,592
2018-01-29 15:05:10,725
$ ./test.sh
arr1: 2018-01-29 15:05:11,592 2018-01-29 15:10:11,592 2018-01-29 15:15:11,592
arr2: 2018-01-29 15:05:10,725 2018-01-29 15:10:10,725 2018-01-29 15:15:11,725
2018-01-29 15:05:11,592
2018-01-29 15:05:10,725
对于bash:
#!/bin/bash
while read -r a b c d e; do
[[ "$c $d" =~ Validating\ control... ]] && echo "$a $b"
[[ "$c $d $e" =~ Done\ validating\ control. ]] && echo "$a $b"
done < file
#/bin/bash
而read-ra-b-c-d-e;做
[[“$c$d”=~验证\控制…]&&echo“$a$b”
[[“$c$d$e”=~Done\validating\control.]&&echo“$a$b”
完成<文件
或
#/bin/bash
而read-ra-b-c-d-e;做
[[“$c$d”=~验证\控制…]&&start=“$a$b”
如果[[“$c$d$e”=~完成\验证\控制。]];然后
stop=“$a$b”
回显“$start”
回音“$stop”
fi
完成<文件
输出:
2018-01-29 15:05:11,592
2018-01-29 15:05:10,725
$ ./test.sh
arr1: 2018-01-29 15:05:11,592 2018-01-29 15:10:11,592 2018-01-29 15:15:11,592
arr2: 2018-01-29 15:05:10,725 2018-01-29 15:10:10,725 2018-01-29 15:15:11,725
2018-01-29 15:05:11,592
2018-01-29 15:05:10,725
这是GNU awk中的一个,它也计算时间差。示例运行两次相同的数据:
$ awk '
BEGIN { FS="[- :,]" } # set FS to get the timestamp parts
/alidating/ { # if matched
if(a!="") { # read the latter value and convert to epoch time:
b=mktime($1 " " $2 " " $3 " " $4 " " $5 " " $6)+($7/10^length($7))
print b-a # calculate time difference
a=b="" # reset vars for the next pair
next # skip to next record
} # below the former of two values is processed:
a=mktime($1 " " $2 " " $3 " " $4 " " $5 " " $6)+($7/(10^length($7)))
}' file file # use same test data twice
0.867
0.867
+($7/10^length($7))
处理分数部分,例如0592将被转换为592/10^3=592/1000=0.592,0,1将转换为1/10=0.1,依此类推。这里是GNU awk中的一个,它也计算时间差。示例运行两次相同的数据:
$ awk '
BEGIN { FS="[- :,]" } # set FS to get the timestamp parts
/alidating/ { # if matched
if(a!="") { # read the latter value and convert to epoch time:
b=mktime($1 " " $2 " " $3 " " $4 " " $5 " " $6)+($7/10^length($7))
print b-a # calculate time difference
a=b="" # reset vars for the next pair
next # skip to next record
} # below the former of two values is processed:
a=mktime($1 " " $2 " " $3 " " $4 " " $5 " " $6)+($7/(10^length($7)))
}' file file # use same test data twice
0.867
0.867
+($7/10^length($7))
处理分数部分,例如0592将转换为592/10^3=592/1000=0.592,0,1将转换为1/10=0.1,依此类推。awk
用于救援
从匹配的行创建时间戳对
$ awk 'BEGIN {FS=OFS=","}
/Validating control/ {s=$1}
/Done validating control/{print s,$1}' file
2018-01-29 15:05:11,2018-01-29 15:05:10
也许在awk
中包含时间增量计算也是有意义的
$ awk 'BEGIN {FS=OFS=","}
/Validating control/ {s=$1}
/Done validating control/{gsub(/[:-]/," ",s);
gsub(/[:-]/," ",$1);
print mktime($1)-mktime(s)}' file
但是,您的数据处于反向时间(在开始前1秒结束),因此结果将为负秒
如果秒后的数字是时间戳的一部分,这可能会更好
$ awk -F'[, ]' '/Validating control/{s=$1":"$2;ms=$3}
/Done validating control/{t=$1":"$2;
print s ms,t $3;
gsub(/[:-]/," ",s);
gsub(/[:-]/," ",t);
print (mktime(t)+($3/1000))-(mktime(s)+(ms/1000))}' file
2018-01-29:15:05:11592 2018-01-29:15:05:10725
-0.867
awk
救援
从匹配的行创建时间戳对
$ awk 'BEGIN {FS=OFS=","}
/Validating control/ {s=$1}
/Done validating control/{print s,$1}' file
2018-01-29 15:05:11,2018-01-29 15:05:10
也许在awk
中包含时间增量计算也是有意义的
$ awk 'BEGIN {FS=OFS=","}
/Validating control/ {s=$1}
/Done validating control/{gsub(/[:-]/," ",s);
gsub(/[:-]/," ",$1);
print mktime($1)-mktime(s)}' file
但是,您的数据处于反向时间(在开始前1秒结束),因此结果将为负秒
如果秒后的数字是时间戳的一部分,这可能会更好
$ awk -F'[, ]' '/Validating control/{s=$1":"$2;ms=$3}
/Done validating control/{t=$1":"$2;
print s ms,t $3;
gsub(/[:-]/," ",s);
gsub(/[:-]/," ",t);
print (mktime(t)+($3/1000))-(mktime(s)+(ms/1000))}' file
2018-01-29:15:05:11592 2018-01-29:15:05:10725
-0.867
下面显示了一个脚本,您可以在其中将输出保存到
bash
中的数组中
$ cat test.sh
#!/bin/bash
# Use sed to print only the relevant lines.
# This also reduces the number of lines to be processed by while loop
sed -n '/Validating control.../,/Done validating control/{//p}' inputFile.txt > /tmp/input_sedVersion.txt
declare -a arr1=()
declare -a arr2=()
i=0
while read -r _date _time _state
do
if [[ "$_state" =~ Validating ]]; then
arr1[$i]="$_date $_time";
else
arr2[$i]="$_date $_time";
((i++));
fi
done < /tmp/input_sedVersion.txt
echo "arr1: ${arr1[@]}"
echo "arr2: ${arr2[@]}"
# Code do something with these arrays
下面显示了一个脚本,您可以在其中将输出保存到
bash
中的数组中
$ cat test.sh
#!/bin/bash
# Use sed to print only the relevant lines.
# This also reduces the number of lines to be processed by while loop
sed -n '/Validating control.../,/Done validating control/{//p}' inputFile.txt > /tmp/input_sedVersion.txt
declare -a arr1=()
declare -a arr2=()
i=0
while read -r _date _time _state
do
if [[ "$_state" =~ Validating ]]; then
arr1[$i]="$_date $_time";
else
arr2[$i]="$_date $_time";
((i++));
fi
done < /tmp/input_sedVersion.txt
echo "arr1: ${arr1[@]}"
echo "arr2: ${arr2[@]}"
# Code do something with these arrays
我忽略了这个问题只标记为“awk”。但是它可能会对awk有所帮助/已完成验证控件。/{stop=$1fs$2}END{print start;print stop}文件Btw:with GNU sed:
sed-En的/^([^]+[^]+)(验证控件…|已完成验证控件。)/\1/p'文件
没有问题。我之所以选择awk,是因为我的原始脚本就是这样使用的,但是如果它完成了任务,并且可以集成到脚本中,我就不会有任何问题。不过Bash解决方案很好。将首先尝试awk建议,看看什么最有效。谢谢!:)我忽略了这个问题只标记为“awk”。但是它可能会对awk有所帮助/已完成验证控件。/{stop=$1fs$2}END{print start;print stop}文件Btw:with GNU sed:sed-En的/^([^]+[^]+)(验证控件…|已完成验证控件。)/\1/p'文件
没有问题。我之所以选择awk,是因为我的原始脚本就是这样使用的,但是如果它完成了任务,并且可以集成到脚本中,我就不会有任何问题。不过Bash解决方案很好。将首先尝试awk建议,看看什么最有效。谢谢!:)它必须与awk一起使用吗?输入文件有多大?最好使用awk,是的,因为我正在集成到一个更大的awk脚本中,该脚本可以解析从几Mb到~3 Gb的任意位置的日志。但是我可以在Awk脚本中调用bash/sh,这样可以证明它更有效。明白了。我添加了一个bash脚本。希望能有帮助。是否一定要使用awk
?输入文件有多大?最好使用awk,是的,因为我正在集成到一个更大的awk脚本中,该脚本可以解析从几Mb到~3 Gb的任意位置的日志。但是我可以在Awk脚本中调用bash/sh,这样可以证明它更有效。明白了。我添加了一个bash脚本。希望有帮助。谢谢你指出这一点。我一定是抄了mi之前的一行