bash排序 - 如何使用时间戳排序

时间:2013-07-24 20:19:41

标签: linux bash sorting timestamp

我需要在linux中使用shell排序对文件进行排序。排序需要基于每个文件行中包含的时间戳值。时间戳是不规则的格式,并没有指定前几个月,天等的零,所以我执行的排序不正确(即它们的格式是“M / D / YYYY H:MI:S AM”;所以所以“10/12/2012 12:16:18 PM”出现在“7/24/2012 12:16:18 PM”之前,这是在“7/24/2012 12:17:18 AM”之前发生的。

是否可以根据时间戳进行排序?

我使用以下命令对文件进行排序:

sort -t= -k3 file.txt -o file.txt.sorted

(使用等号作为分隔符=> -t=;使用第3列作为排序列=> -k3

示例文件如下:

<r id="abcd" t="10/12/2012 12:16:17 AM"><d><nv n="name" v="868" /><nv n="name0" v="73" /><nv n="name1" v="13815004" /></d></r>
<r id="defg" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="abcd" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="zxy" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="59542676" /></d></r>
<r id="fghj" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="38" /><nv n="name0" v="0" /><nv n="name1" v="3004537" /></d></r>
<r id="defg" t="7/24/2012 12:16:18 AM"><d><nv n="name" v="177" /><nv n="name0" v="0" /><nv n="name1" v="5888870" /></d></r>

2 个答案:

答案 0 :(得分:3)

linux date命令可以很好地解析这样的日期,并且可以将它们转换为更多可排序的东西,比如简单的unix-time整数。

示例:

cat file | while read line; do
    datestring=$(sed -e 's/^.* t="\([^"]*\)".*$/\1/' <<<"$line")
    echo "$(date -d "$datestring" +%s) $line"
done | sort -n

如果你想再次删除unix时间戳,你可以通过适当的cut调用传递它。

答案 1 :(得分:1)

sort是一个很好的工具,但它没有足够的花里胡哨来分开伪xml,将属性转换为合理的时间值,然后对其进行排序。

但是,这样的工具确实存在。虽然执行此操作的最佳方法可能是使用XSLT转换,但如果文件实际上与示例命令所期望的一致,则可以使用cut -d'"' -f4提取时间值,并且可以将每个转换为更多date的合理格式。例如(需要GNU date):

paste <(cut -d'"' -f4 file.txt | date -f- +%s) file.txt | sort -n | cut -f2-

提取日期时间,每行一个;将它们提供给日期以将它们转换为秒 - 自 - 纪元;在每行的开头粘贴每个时间戳;以数字方式对粘贴的结果进行排序,现在在开头使用数字时间戳,最后删除时间戳以恢复原始文件。

测试:

$ cat >file.txt <<'EOF'
<r id="abcd" t="10/12/2012 12:16:17 AM"><d><nv n="name" v="868" /><nv n="name0" v="73" /><nv n="name1" v="13815004" /></d></r>
<r id="defg" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="abcd" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="zxy" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="59542676" /></d></r>
<r id="fghj" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="38" /><nv n="name0" v="0" /><nv n="name1" v="3004537" /></d></r>
<r id="defg" t="7/24/2012 12:16:18 AM"><d><nv n="name" v="177" /><nv n="name0" v="0" /><nv n="name1" v="5888870" /></d></r>
EOF
$ paste <(cut -d'"' -f4 file.txt | date -f- +%s) file.txt | sort -n | cut -f2-
<r id="defg" t="7/24/2012 12:16:18 AM"><d><nv n="name" v="177" /><nv n="name0" v="0" /><nv n="name1" v="5888870" /></d></r>
<r id="abcd" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="defg" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="0" /></d></r>
<r id="fghj" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="38" /><nv n="name0" v="0" /><nv n="name1" v="3004537" /></d></r>
<r id="zxy" t="7/24/2012 12:16:17 PM"><d><nv n="name" v="0" /><nv n="name0" v="0" /><nv n="name1" v="59542676" /></d></r>
<r id="abcd" t="10/12/2012 12:16:17 AM"><d><nv n="name" v="868" /><nv n="name0" v="73" /><nv n="name1" v="13815004" /></d></r>