使用 awk 从日志中提取字段并将它们聚合为新命令
Extract fields from logs with awk and aggregate them for a new command
我有这样的日志:
2018-10-05 09:12:38 286 <190>1 2018-10-05T09:12:38.474640+00:00 app web - - Class uuid=uuid-number-one cp=xxx action='xxxx'
2018-10-05 10:11:23 286 <190>1 2018-10-05T10:11:23.474640+00:00 app web - - Class uuid=uuid-number-two cp=xxx action='xxxx'
我需要提取 uuid
和 运行 第二个查询:
./getlogs --search 'uuid-number-one OR uuid-number-two'
对于第一个查询,我这样做是为了提取 uuid
:
./getlogs | grep 'uuid' | awk 'BEGIN {FS="="} { print }' | cut -d' ' -f1
我的三个问题:
- 我想我可以摆脱
grep
和 cut
并只使用 awk
?
- 如何只捕获
uuid
的值。我尝试了 awk '/uuid=\S*/{ print }'
或 awk 'BEGIN {FS="uuid=\S*"} { print }'
但失败了。
- 我如何汇总结果并将其转换为一个 shell 变量,以便在新命令之后使用?
能否请您尝试以下操作(在所示示例和 BASH 环境中测试)。
awk 'match([=10=],/uuid=[^ ]*/){print substr([=10=],RSTART+5,RLENGTH-5)}' Input_file
解决方案 2: 如果您的 uid
中没有 space,请使用以下方法。
awk '{sub(/.*uuid=/,"");sub(/ .*/,"")} 1' Input_file
解决方案 3: 使用 sed
以下可能对您有帮助(考虑到 uid 没有任何 space 在其值中)。
sed 's/\(.*uuid=\)\([^ ]*\)\(.*\)//' Input_file
解决方案 4: 对显示的示例使用 awk
字段分隔符方法。
awk -F'uuid=| cp' '{print }' Input_file
要将所有值连接到一个 shell 变量中,请使用以下内容。
shell_var=$(awk 'match([=14=],/uuid=[^ ]*/){val=val?val OFS substr([=14=],RSTART+5,RLENGTH-5):substr([=14=],RSTART+5,RLENGTH-5)} END{print val}' Input_file)
您可以定义两个字段分隔符:
$ awk -F['= '] '/uuid/{print }' file
结果:
uuid-number-one
uuid-number-two
问题 2:
awk 中的模式部分只是选择要处理的行。它不会更改 </code> 或 <code>NF
等内部变量。之后您需要进行更换:
$ awk '/uuid=/{print gensub(/.*uuid=(\S*).*/, "\1", "")}' file
问题 3:
var=$(awk -F['= '] '/uuid/{r=r","}END{print substr(r,2)}' file)
为每一行实施实际聚合(此处r=r","
)。
我有这样的日志:
2018-10-05 09:12:38 286 <190>1 2018-10-05T09:12:38.474640+00:00 app web - - Class uuid=uuid-number-one cp=xxx action='xxxx'
2018-10-05 10:11:23 286 <190>1 2018-10-05T10:11:23.474640+00:00 app web - - Class uuid=uuid-number-two cp=xxx action='xxxx'
我需要提取 uuid
和 运行 第二个查询:
./getlogs --search 'uuid-number-one OR uuid-number-two'
对于第一个查询,我这样做是为了提取 uuid
:
./getlogs | grep 'uuid' | awk 'BEGIN {FS="="} { print }' | cut -d' ' -f1
我的三个问题:
- 我想我可以摆脱
grep
和cut
并只使用awk
? - 如何只捕获
uuid
的值。我尝试了awk '/uuid=\S*/{ print }'
或awk 'BEGIN {FS="uuid=\S*"} { print }'
但失败了。 - 我如何汇总结果并将其转换为一个 shell 变量,以便在新命令之后使用?
能否请您尝试以下操作(在所示示例和 BASH 环境中测试)。
awk 'match([=10=],/uuid=[^ ]*/){print substr([=10=],RSTART+5,RLENGTH-5)}' Input_file
解决方案 2: 如果您的 uid
中没有 space,请使用以下方法。
awk '{sub(/.*uuid=/,"");sub(/ .*/,"")} 1' Input_file
解决方案 3: 使用 sed
以下可能对您有帮助(考虑到 uid 没有任何 space 在其值中)。
sed 's/\(.*uuid=\)\([^ ]*\)\(.*\)//' Input_file
解决方案 4: 对显示的示例使用 awk
字段分隔符方法。
awk -F'uuid=| cp' '{print }' Input_file
要将所有值连接到一个 shell 变量中,请使用以下内容。
shell_var=$(awk 'match([=14=],/uuid=[^ ]*/){val=val?val OFS substr([=14=],RSTART+5,RLENGTH-5):substr([=14=],RSTART+5,RLENGTH-5)} END{print val}' Input_file)
您可以定义两个字段分隔符:
$ awk -F['= '] '/uuid/{print }' file
结果:
uuid-number-one
uuid-number-two
问题 2:
awk 中的模式部分只是选择要处理的行。它不会更改 </code> 或 <code>NF
等内部变量。之后您需要进行更换:
$ awk '/uuid=/{print gensub(/.*uuid=(\S*).*/, "\1", "")}' file
问题 3:
var=$(awk -F['= '] '/uuid/{r=r","}END{print substr(r,2)}' file)
为每一行实施实际聚合(此处r=r","
)。