根据特定字符串过滤行,然后只打印一些更大的属性
Filter lines based on certain string and then print only some attributes greater
我有一个包含数百万行日志的大文本文件。
我想过滤所有满足以下条件的行
- url 应该是
url=/v2/testB
- totalTime 值应大于 500
INFO|id=1|totaltime=5000|httpmethod=POST|url=/v1/testA
INFO|id=2|totaltime=200|httpmethod=POST|url=/v2/testB
INFO|id=3|totaltime=1000|httpmethod=POST|url=/v2/testB
INFO|id=4|totaltime=501|httpmethod=POST|url=/v2/testB
结果:-
id=3,totaltime=1000
id=4,totaltime=501
我试过用多个awk然后放if block,不知道能不能很快搞定?谢谢!
while IFS= read -r line; do
value=`echo $line|grep "url=/v2/testB" | awk -F"totaltime=" '{ print }'| awk -F"|" '{ print }'`
if (( $value > 500 )); then
echo $line
fi
done < file.log
你可以使用这个 awk:
awk -F '|' -v OFS=, '$NF == "url=/v2/testB" {v=; sub(/^totaltime=/, "", v); if (v+0 > 500) print , }' file
id=3,totaltime=1000
id=4,totaltime=501
为了使其更具可读性:
awk -F '|' -v OFS=, '
$NF == "url=/v2/testB" {
v =
sub(/^totaltime=/, "", v)
if (v+0 > 500)
print ,
}' file
如果你有 gnu-awk
那么它可以减少到:
awk -F '|' -v OFS=, '$NF == "url=/v2/testB" &&
gensub(/^totaltime=/, "", "1", )+0 > 500 {print , }' file
v+0
在 awk 中是 shorthand,用于将字符串值转换为数字。
看来你运气不错:
awk -F'|' 'BEGIN{FS="|"; OFS=","}
{ url = substr($NF,index($NF,"=")+1)
totaltime = substr(,index(,"=")+1)
}
(url == "/v1/testB") && (totaltime+0 > 500) { print , }
' file
$ awk -F'|' -v OFS=',' '{split(,t,/=/)} =="url=/v2/testB" && t[2]>500{print , }' file
id=3,totaltime=1000
id=4,totaltime=501
使用您展示的示例,请尝试执行以下 awk
程序。
awk -F'\||totaltime=' '$NF=="url=/v2/testB" && >500{print ",totaltime="}' Input_file
解释:下面是对上述代码的详细解释。
- 使用
awk
程序中的 -F
选项设置字段分隔符。
- 为 Input_file.
的所有行将字段分隔符设置为 |
和 totaltime=
- 在主程序中,检查条件:
a- 如果
$NF
(最后一个字段)等于 url=/v2/testB
并且
b- 第 4 个字段大于 500 然后做:
- 打印当前行的第二个字段,后跟字符串
,totaltime=
,然后是 OP 要求输出的第 4 个字段。
所有 awk 解决方案都很棒,如果这是一个解决方案,请使用它们。
如果您想解决 Bash 的问题,您可以这样做:
while IFS='|' read -r id ti; do
[[ "${ti#*=}" -gt 500 ]] && printf "%s,%s\n" "$id" "$ti"
done < <(grep 'url=/v2/testB$' file | cut -d '|' -f 2,3)
或者,您可以删除 cut
并保留所有五个字段:
while IFS='|' read -r c1 c2 c3 c4 c5; do
[[ "${c3#*=}" -gt 500 ]] && printf "%s,%s\n" "$c2" "$c5"
done < <(grep 'url=/v2/testB$' file)
要么打印:
id=3,totaltime=1000
id=4,totaltime=501
我有一个包含数百万行日志的大文本文件。
我想过滤所有满足以下条件的行
- url 应该是
url=/v2/testB
- totalTime 值应大于 500
INFO|id=1|totaltime=5000|httpmethod=POST|url=/v1/testA
INFO|id=2|totaltime=200|httpmethod=POST|url=/v2/testB
INFO|id=3|totaltime=1000|httpmethod=POST|url=/v2/testB
INFO|id=4|totaltime=501|httpmethod=POST|url=/v2/testB
结果:-
id=3,totaltime=1000
id=4,totaltime=501
我试过用多个awk然后放if block,不知道能不能很快搞定?谢谢!
while IFS= read -r line; do
value=`echo $line|grep "url=/v2/testB" | awk -F"totaltime=" '{ print }'| awk -F"|" '{ print }'`
if (( $value > 500 )); then
echo $line
fi
done < file.log
你可以使用这个 awk:
awk -F '|' -v OFS=, '$NF == "url=/v2/testB" {v=; sub(/^totaltime=/, "", v); if (v+0 > 500) print , }' file
id=3,totaltime=1000
id=4,totaltime=501
为了使其更具可读性:
awk -F '|' -v OFS=, '
$NF == "url=/v2/testB" {
v =
sub(/^totaltime=/, "", v)
if (v+0 > 500)
print ,
}' file
如果你有 gnu-awk
那么它可以减少到:
awk -F '|' -v OFS=, '$NF == "url=/v2/testB" &&
gensub(/^totaltime=/, "", "1", )+0 > 500 {print , }' file
v+0
在 awk 中是 shorthand,用于将字符串值转换为数字。
看来你运气不错:
awk -F'|' 'BEGIN{FS="|"; OFS=","}
{ url = substr($NF,index($NF,"=")+1)
totaltime = substr(,index(,"=")+1)
}
(url == "/v1/testB") && (totaltime+0 > 500) { print , }
' file
$ awk -F'|' -v OFS=',' '{split(,t,/=/)} =="url=/v2/testB" && t[2]>500{print , }' file
id=3,totaltime=1000
id=4,totaltime=501
使用您展示的示例,请尝试执行以下 awk
程序。
awk -F'\||totaltime=' '$NF=="url=/v2/testB" && >500{print ",totaltime="}' Input_file
解释:下面是对上述代码的详细解释。
- 使用
awk
程序中的-F
选项设置字段分隔符。 - 为 Input_file. 的所有行将字段分隔符设置为
- 在主程序中,检查条件:
a- 如果
$NF
(最后一个字段)等于url=/v2/testB
并且 b- 第 4 个字段大于 500 然后做: - 打印当前行的第二个字段,后跟字符串
,totaltime=
,然后是 OP 要求输出的第 4 个字段。
|
和 totaltime=
所有 awk 解决方案都很棒,如果这是一个解决方案,请使用它们。
如果您想解决 Bash 的问题,您可以这样做:
while IFS='|' read -r id ti; do
[[ "${ti#*=}" -gt 500 ]] && printf "%s,%s\n" "$id" "$ti"
done < <(grep 'url=/v2/testB$' file | cut -d '|' -f 2,3)
或者,您可以删除 cut
并保留所有五个字段:
while IFS='|' read -r c1 c2 c3 c4 c5; do
[[ "${c3#*=}" -gt 500 ]] && printf "%s,%s\n" "$c2" "$c5"
done < <(grep 'url=/v2/testB$' file)
要么打印:
id=3,totaltime=1000
id=4,totaltime=501