Linux Shell脚本如何正确截取以字符2开头的日期子串
问题背景
现有文件FILE1.TXT,文件内每行共两种格式:
- 格式1:
0020220101 - 格式2:
01 20220101
需求为提取每行中以字符2开头的8位日期部分,预期输出结果为20220101。
之前尝试执行的命令如下:
t_FILE_DT1='awk -F"2" '{PRINT $NF}' FILE1.TXT' t_FILE_DT2='cut -d'2' -f2- FILE1.TXT' echo "$t_FILE_DT1" echo "$t_FILE_DT2"
执行后第一条命令输出0101,第二条命令输出0220101,均不符合预期。
原有命令错误原因
- 分隔符选择逻辑错误
两个命令都把字符2作为字段分隔符,但目标日期本身就是以2开头、内部也包含2,用2做分隔符会直接把完整日期拆成多个碎片,根本不可能拿到完整的日期串。- 对
0020220101这行来说,按2拆分后得到的字段依次是00、0、空字符串、0101,awk取最后一个字段$NF自然得到0101 - cut取第二个字段到末尾的内容,拿到的是第一个
2之后的所有字符0220101,开头的2被当成分隔符切掉了,结果不对
- 对
- 语法写法错误
- awk的打印关键字是小写
print,大写PRINT会触发语法报错 - shell变量赋值时单引号嵌套错误,外层用单引号包裹命令、内部直接写单引号会导致shell解析中断,命令无法按预期执行
- awk的打印关键字是小写
正确实现方案
核心思路是直接匹配以2开头、后续跟7位数字的8位字符串,这是符合日期格式的固定特征,不用关心日期前面的内容是什么,两种行格式都能适配。
- 方案1:用grep实现,写法最简洁
# -o 参数表示只输出匹配到的内容,不输出整行 grep -o '2[0-9]\{7\}' FILE1.TXT
- 方案2:用sed实现
# 匹配整行内容,替换为提取到的日期部分后打印 sed -n 's/.*\(2[0-9]\{7\}\).*/\1/p' FILE1.TXT
- 方案3:用awk实现
# 用match函数匹配日期正则,输出匹配到的结果 awk 'match($0,/2[0-9]{7}/,res){print res[0]}' FILE1.TXT
以上三个命令执行后都能正确输出20220101。
内容的提问来源于stack exchange,提问作者DAC
相关产品推荐
相关产品推荐

