Bash文本处理需求:提取文件信息并转换MySQL时间戳格式
解决连续空格分隔文本的列提取与时间格式转换问题
我来帮你搞定这个麻烦!你用cut命令遇到的问题很典型——它没法把连续空格当成单个分隔符,而且列号会因为内容长度变化乱掉。换成awk就能完美解决,它默认会把任意连续空白(空格、制表符)当成单个分隔符,正好适配这种类似ls输出的文本格式。
核心解决方案命令
针对你的需求,直接用这条awk命令就能得到预期结果:
awk '{ # 建立月份缩写到数字的映射表 month_map["Jan"]="01"; month_map["Feb"]="02"; month_map["Mar"]="03" month_map["Apr"]="04"; month_map["May"]="05"; month_map["Jun"]="06" month_map["Jul"]="07"; month_map["Aug"]="08"; month_map["Sep"]="09" month_map["Oct"]="10"; month_map["Nov"]="11"; month_map["Dec"]="12" # 注意:ls输出中当年的文件不会显示年份,这里根据你的示例设为2019,可按需修改 year=2019 # 拼接成MySQL timestamp格式:YYYY-MM-DD HH:MM:SS timestamp=year "-" month_map[$6] "-" sprintf("%02d", $7) " " $8 ":00" # 输出:文件路径 所有者 时间戳,用制表符分隔 print $9 "\t" $3 "\t" timestamp }' text.txt
命令细节解释
- 提取所有者:
$3对应文本中的第3列(也就是示例里的wls1) - 提取文件路径:
$9对应文本中的第9列,因为你的示例里文件名没有空格,所以直接取这一列就是完整路径 - 时间格式转换:
- 用
month_map把月份缩写(比如Nov)转成两位数字(11) - 用
sprintf("%02d", $7)把单个数字的日期(比如1)补零变成01 - 拼接时分并补零秒数,最终得到符合要求的
2019-11-01 00:42:00格式
- 用
适配带空格的文件名
如果你的文件路径/名称包含空格,上面的$9就不够用了,需要把从第9列到最后一列拼接成完整路径,修改后的命令如下:
awk '{ month_map["Jan"]="01"; month_map["Feb"]="02"; month_map["Mar"]="03" month_map["Apr"]="04"; month_map["May"]="05"; month_map["Jun"]="06" month_map["Jul"]="07"; month_map["Aug"]="08"; month_map["Sep"]="09" month_map["Oct"]="10"; month_map["Nov"]="11"; month_map["Dec"]="12" year=2019 timestamp=year "-" month_map[$6] "-" sprintf("%02d", $7) " " $8 ":00" # 拼接带空格的完整路径 full_path="" for(i=9; i<=NF; i++) { full_path = full_path " " $i } full_path = substr(full_path, 2) # 去掉开头多余的空格 print full_path "\t" $3 "\t" timestamp }' text.txt
为什么不用cut?因为cut是按固定分隔符拆分的,连续空格会被当成多个分隔符,导致列号完全混乱,而awk的默认字段分隔符就是任意连续空白,天生适合处理这种场景。
内容的提问来源于stack exchange,提问作者user3055756
相关产品推荐
相关产品推荐

