我有一个如下文本文件
11:00AM JOHN STAMOS 1983-08-07 I like Pizza Hut
12:00AM JACK SPARROW PIRATE 1886-09-07 I like Pizza Hut and DOminoz
11:00AM SANTA 1986-04-01 I like cold beer
如何在日期列上对上述文件进行排序?我面临的问题是由于可变长度名称列。有些人有第一个中间姓,因为有些人只有名字等等。
答案 0 :(得分:1)
您需要做的是将日期复制到前面,然后排序默认情况下将整行用作排序键。然后再次删除日期。
我使用sed从nnnn-nn-nn格式中找出所有(最后)日期的内容,然后将日期复制到前面。
排序后,只需使用sed(或cut -c11-会更容易)再次从前面删除日期。
这适用于linux:
sed 's/^\(.* \([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] \)\)/\2\1/' |
sort |
sed 's/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] //'
,并提供:
12:00AM JACK SPARROW PIRATE 1886-09-07 I like Pizza Hut and DOminoz
11:00AM JOHN STAMOS 1983-08-07 I like Pizza Hut
11:00AM SANTA 1986-04-01 I like cold beer
这适用于您的数据,但如果您的数据发生变化(例如,您在一行中有多个日期),则很容易变得非常尴尬。
答案 1 :(得分:1)
sed 's/\([0-9]\{4\}\(-[0-9]\{2\}\)\{2\}\)/|\1/' | sort -t '|' -k 2| sed s/'|'//
答案 2 :(得分:0)
cat file.txt | python -c 'import re, sys; print "".join(sorted(sys.stdin, key=lambda x:re.findall("\d{4}-\d{2}-\d{2}",x)))'
答案 3 :(得分:0)
Pure Bash:
declare -a array
declare -a order
IFS=$'\n'
array=( $(cat "$infile") )
index=0
for line in "${array[@]}"; do
[[ "$line" =~ ([[:digit:]]+)-([[:digit:]]+)-([[:digit:]]+) ]]
key="${BASH_REMATCH[1]}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
if [ -z "${order[key]}" ] ; then
order[key]="$index"
else
order[key]="${order[key]} $index"
fi
((index++))
done < "$infile"
IFS=' '
for key in ${order[*]}; do
printf "%s\n" "${array[key]}"
done
从日期生成索引并将其用作排序列表。