Shell脚本排序列表

时间:2009-11-02 16:51:17

标签: algorithm bash sorting

我有一个包含以下内容的列表:

VIP NAME DATE  ARRIVE_TIME FLIGHT_TIME

1  USER1 11-02    20.00    21.00
3  USER2 11-02    20.45    21.45
4  USER2 11-03    20.00    21.30
2  USER1 11-04    17.20    19.10

我想用shell脚本对这个和类似的列表进行排序。结果应该是一个新列表,其中的行不会发生冲突。 VIP 1是最重要的,如果任何号码较大的VIP在{1}} ARRIVE_TIME之前{1}}的VIP 1应在同一天删除此行,那么FLIGHT_TIME号码应该用于决定VIPARRIVE_TIMEFLIGHT_TIME发生冲突时要保留哪些行。同样,VIP 2比VIP 3更重要,依此类推。

这是非常先进的,对于如何解决这个问题的想法我完全是空的。

2 个答案:

答案 0 :(得分:2)

您可以使用unix sort命令执行此操作:

有一个如何设置主键和辅助键的示例:

Example

uniq命令是删除欺骗所需的。

答案 1 :(得分:1)

这可能会让你开始:

  • 我忽略了标题行。您可以使用head删除它,或在for循环中跳过它。
  • 按日期,到达,离开和贵宾号码对航班进行排序 - 将贵宾号作为排序键可以在以后简化逻辑。
  • 我将结果保存在数组中,但您可以将其重定向到临时文件,并使用while read line; do ...; done <tempfile循环一次读取一行。
  • 我正在使用间接使事情更具可读性(命名字段而不是直接使用数组索引 - 感叹号意味着间接而不是“不”)
  • 对于与最近打印行同日发生的结果中的每一行,将其到达时间与上一航班的出发时间进行比较
  • 回应适当的行。
  • 保存日期和出发时间以供日后比较。
  • 如果对您的数据更有效,则应将<比较调整为<=

这是脚本:

#!/bin/bash
saveIFS="$IFS"
IFS=$'\n'
flights=($(sort -k3,3 -k4,4n -k5,5n -k1,1n flights ))
IFS="$saveIFS"

date=fields[2]
arrive=fields[3]
depart=fields[4]

for line in "${flights[@]}"
do
    fields=($line)
    if [[ ${!date} == $prevdate && ${!arrive} < $prevdep ]]
    then
        echo "deleted: $line"    # or you could do something else here
    else
        echo $line
        prevdep=${!depart}
        prevdate=${!date}
    fi
done