如何将Shell命令last的输出转换为JSON格式?是否有对应实现方式?
这是个超实用的需求!把last命令的输出转成JSON格式,确实有好几种靠谱的实现方式,我给你整理几个常用的方案,从无依赖的快速解决到灵活的脚本实现都有:
方法1:用Awk手动解析(无需额外依赖)
Awk是绝大多数Unix/Linux系统默认自带的工具,适合快速处理文本并转成JSON,不需要安装任何额外软件。下面的脚本会自动处理last输出里的常见情况,比如用户仍在线(still logged in)、无IP地址的本地登录等:
last | awk ' BEGIN { print "[" } # 跳过最后一行的"wtmp begins..."提示 $0 !~ /^wtmp/ { # 除了第一条记录,前面加逗号保证JSON格式合法 if (NR > 1) print "," # 提取核心字段 name = $1 tty = $2 # 判断第三字段是否是IP地址,不是的话设为"-" ip = ($3 ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ ? $3 : "-") # 拼接登录时间(字段4-7) start_time = $4 " " $5 " " $6 " " $7 # 处理用户仍在线的情况 if ($8 == "-") { end_time = "still logged in" duration = "-" } else { end_time = $8 " " $9 " " $10 " " $11 duration = $12 } # 输出JSON对象 printf("{\"name\":\"%s\",\"tty\":\"%s\",\"ip\":\"%s\",\"start_time\":\"%s\",\"end_time\":\"%s\",\"duration\":\"%s\"}", name, tty, ip, start_time, end_time, duration) } END { print "\n]" } '
方法2:用Python脚本(更灵活,适合复杂场景)
如果需要处理更多边缘情况(比如不同系统的last输出格式差异、特殊字符转义),Python会是更稳妥的选择,它的JSON模块能自动处理格式合法性:
import subprocess import json import re def parse_last_record(line): # 匹配last输出的行结构,兼容多种情况 pattern = re.compile( r'^(\S+)\s+(\S+)\s+(\S*)\s+' r'(\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2})\s+' r'(-|\w{3}\s+\w{3}\s+\d{1,2}\s+\d{2}:\d{2})\s+' r'(\((?:\d+:\d+)|still logged in\))?$' ) match = pattern.match(line) if not match: return None name, tty, ip, start_time, end_time, duration = match.groups() # 补全空IP的情况 if not ip: ip = "-" # 处理仍在线的记录 if end_time == "-": end_time = "still logged in" duration = "-" else: # 去掉时长字段的括号 duration = duration.strip("()") return { "name": name, "tty": tty, "ip": ip, "start_time": start_time, "end_time": end_time, "duration": duration } # 执行last命令并读取输出 last_output = subprocess.check_output(["last"], text=True).splitlines() records = [] for line in last_output: # 跳过最后一行的wtmp起始提示 if line.startswith("wtmp begins"): break record = parse_last_record(line) if record: records.append(record) # 格式化输出JSON print(json.dumps(records, indent=2))
方法3:用现成工具链(适合快速批量转换)
如果你已经安装了csvkit(可以通过pip install csvkit或者系统包管理器安装),可以先把last输出转成CSV,再转成JSON:
# 过滤掉wtmp提示行,转成CSV,再转成JSON last | grep -v "^wtmp" | awk '{print $1","$2","$3","$4" "$5" "$6" "$7","$8" "$9" "$10" "$11","$12}' | csvjson -c name,tty,ip,start_time,end_time,duration
注意事项
不同Linux发行版或Unix系统的last输出格式可能略有差异(比如时间字段的顺序、是否包含时区),如果上面的脚本不适用,可以先执行last查看自己系统的输出结构,再调整字段提取的逻辑。
内容的提问来源于stack exchange,提问作者rotwar
相关产品推荐
相关产品推荐

