将系统日志转换为 csv macOS
Convert system log to csv macOS
给定日志行
Sep 25 20:10:44 Evans-MacBook-Pro-2 com.apple.xpc.launchd[1] (com.oracle.oss.mysql.mysqld[50806]): Service could not initialize: Unable to set current working directory. error = 2: No such file or directory, path = /usr/local/mysql: 19H114: xpcproxy + 14537 [673][F3151671-4794-3393-AF04-C3421B7647F3]: 0x2
我想将其转换为 csv 文件,这样 csv 的格式如下:
DATE, SYSTEM, SERVICE, MESSAGE
Sep 25 20:10:44, macbook, com.apple.xpc.launchd[1], (com.oracle.oss.mysql.mysqld[50806]): Service could not initialize: Unable to set current working directory. error = 2: No such file or directory, path = /usr/local/mysql: 19H114: xpcproxy + 14537 [673][F3151671-4794-3393-AF04-C3421B7647F3]: 0x2
这里棘手的部分是消息可以包含逗号。我从命令开始
cat system.log | grep error
并从这里开始建设。这几乎完成了
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
printf '%s, %s, %s, "%s"\n' "$d1 $d2 $d3" $sys $svc "${msg//\"/\"\"}"
done
唯一的问题是解析消息
这是在 zsh
和 bash
中执行此操作的一种方法:
printf 'DATE, SYSTEM, SERVICE, MESSAGE\n'
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
printf '%s, %s, %s, "%s"\n' "$d1 $d2 $d3" $sys $svc "${msg//\"/\"\"}"
done
此脚本基于一些假设:
- 日期、系统和服务字段没有嵌入 space 除了示例中显示的内容。
csv
文件的使用者可以处理用于消息字段的引用。
在 .csv 文件中支持逗号的标准方法是用双引号将字段括起来,然后通过重复双引号来转义双引号。 csv 文件上的维基百科条目有更多信息:https://en.wikipedia.org/wiki/Comma-separated_values
虽然这样的引用很常见,但绝不是普遍的。如果 csv 消费者无法处理引用的文件,一个简单的答案是将逗号更改为分号:
print 'DATE, SYSTEM, SERVICE, MESSAGE'
grep error system.log \
| while IFS=' ' read -A fl; do
ary=("$fl[1,3]" "$fl[4]" "$fl[5]" "${fl[6,-1]//,/;}")
print ${(j:, :)ary}
done
请注意,此版本使用一些特定于 zsh 的语法:print
、read -A
来为数组赋值(它还将连续的 space 折叠成单个 space), 和 j
(join) 参数扩展标志。
已添加:某些 'csv' 文件的使用者可能会更好地使用制表符分隔符。
这是 zsh
:
中的一个简单更改
printf 'DATE\tSYSTEM\tSERVICE\tMESSAGE\n'
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
ary=("$d1 $d2 $d3" "$sys" "$svc" "$msg")
print ${(pj:\t:)ary}
done
给定日志行
Sep 25 20:10:44 Evans-MacBook-Pro-2 com.apple.xpc.launchd[1] (com.oracle.oss.mysql.mysqld[50806]): Service could not initialize: Unable to set current working directory. error = 2: No such file or directory, path = /usr/local/mysql: 19H114: xpcproxy + 14537 [673][F3151671-4794-3393-AF04-C3421B7647F3]: 0x2
我想将其转换为 csv 文件,这样 csv 的格式如下:
DATE, SYSTEM, SERVICE, MESSAGE
Sep 25 20:10:44, macbook, com.apple.xpc.launchd[1], (com.oracle.oss.mysql.mysqld[50806]): Service could not initialize: Unable to set current working directory. error = 2: No such file or directory, path = /usr/local/mysql: 19H114: xpcproxy + 14537 [673][F3151671-4794-3393-AF04-C3421B7647F3]: 0x2
这里棘手的部分是消息可以包含逗号。我从命令开始
cat system.log | grep error
并从这里开始建设。这几乎完成了
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
printf '%s, %s, %s, "%s"\n' "$d1 $d2 $d3" $sys $svc "${msg//\"/\"\"}"
done
唯一的问题是解析消息
这是在 zsh
和 bash
中执行此操作的一种方法:
printf 'DATE, SYSTEM, SERVICE, MESSAGE\n'
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
printf '%s, %s, %s, "%s"\n' "$d1 $d2 $d3" $sys $svc "${msg//\"/\"\"}"
done
此脚本基于一些假设:
- 日期、系统和服务字段没有嵌入 space 除了示例中显示的内容。
csv
文件的使用者可以处理用于消息字段的引用。
在 .csv 文件中支持逗号的标准方法是用双引号将字段括起来,然后通过重复双引号来转义双引号。 csv 文件上的维基百科条目有更多信息:https://en.wikipedia.org/wiki/Comma-separated_values
虽然这样的引用很常见,但绝不是普遍的。如果 csv 消费者无法处理引用的文件,一个简单的答案是将逗号更改为分号:
print 'DATE, SYSTEM, SERVICE, MESSAGE'
grep error system.log \
| while IFS=' ' read -A fl; do
ary=("$fl[1,3]" "$fl[4]" "$fl[5]" "${fl[6,-1]//,/;}")
print ${(j:, :)ary}
done
请注意,此版本使用一些特定于 zsh 的语法:print
、read -A
来为数组赋值(它还将连续的 space 折叠成单个 space), 和 j
(join) 参数扩展标志。
已添加:某些 'csv' 文件的使用者可能会更好地使用制表符分隔符。
这是 zsh
:
printf 'DATE\tSYSTEM\tSERVICE\tMESSAGE\n'
grep error system.log \
| while IFS=' ' read d1 d2 d3 sys svc msg; do
ary=("$d1 $d2 $d3" "$sys" "$svc" "$msg")
print ${(pj:\t:)ary}
done