如何对姓名与日期间空格数不一致的文件按日期排序且保留原格式?
如何对姓名与日期间空格数不一致的文件按日期排序且保留原格式?
嘿,我懂你的痛点——既要按真实的日期先后排序,又不想动原文件里姓名和日期间的那些空格,之前的方法要么排序逻辑不对,要么把空格搞没了,确实挺闹心的。
我给你个完美解决这个问题的方案,既能保证日期排序的正确性,还能完完整整保留原文件的格式:
awk '{ split($2, date_parts, "/") sort_key = date_parts[3] date_parts[2] date_parts[1] print sort_key "|" $0 }' name_and_birthday.txt | sort -k1,1 | awk -F"|" '{print $2}' > sorted_by_birth.txt
我给你拆解下这个命令的逻辑:
- 第一步用
awk处理每一行:- 不管姓名和日期间有多少空格,
awk默认会把连续空白当成分隔符,所以$2就是你要的日期字段;我们把这个日期按/拆分成日、月、年三个部分 - 把这三个部分拼成
YYYYMMDD格式的字符串当排序键——这种格式的妙处在于,字符串排序的结果和真实日期的先后顺序完全一致 - 把这个排序键和原行用
|(一个不会出现在你原文件里的分隔符)拼在一起输出
- 不管姓名和日期间有多少空格,
- 然后用
sort -k1,1按我们生成的排序键排序,这一步就会把行按真实日期从早到晚排好 - 最后再用
awk把前面加的排序键去掉,输出原行——这样原文件里的所有空格都完完整整保留下来了
为什么你之前的方法不行呢?给你捋一捋:
- 你第一个用
sort -k2,2的命令,是按日期的字符串字典序排序的,比如15/09/1976(1976年)因为开头是1,会排在03/01/1980(1980年)后面,这显然不是你要的真实日期顺序 - 第二个用
awk '{$1=$1}1'的方法,会把所有连续空白压缩成单个空格,自然就破坏了你原本的格式,不符合要求
这个方法的好处就是,全程没碰原行的内容,只是临时加了个排序用的“辅助键”,排序完就扔掉,完美解决你的需求。要是你的原文件里碰巧有|这个字符,换个其他不常用的字符比如@或者#就行,只要保证它不会出现在原文件里就行。
备注:内容来源于stack exchange,提问作者Mykola
相关产品推荐
相关产品推荐

