如何使用shell脚本对以下文件进行排序?

时间:2010-08-14 07:37:23

标签: sorting shell

我有一个如下文本文件

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

如何在日期列上对上述文件进行排序?我面临的问题是由于可变长度名称列。有些人有第一个中间姓,因为有些人只有名字等等。

4 个答案:

答案 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

从日期生成索引并将其用作排序列表。

相关问题