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



我需要在linux中使用shell排序对文件进行排序。排序需要基于每个文件行中包含的时间戳值。时间戳的格式不规则,没有指定月份、日期等的前导零,因此我执行的排序不正确(即,它们的格式是"M/D/YYYY H:MI:S am";所以"2012年12月10日12:16:18 PM"在"2012年7月24日12:16:18PM"之前,"2012年24月7日12:17:18AM"之前)。

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

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

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

(使用等号作为分隔符=>-t=;使用第三列作为排序列=>-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>

linux date命令在解析这样的日期方面做得很好,它可以将它们转换为更可排序的东西,比如简单的unix时间整数。

示例:

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

如果您希望再次删除unix时间戳,那么您可以通过适当的cut调用来传递它。

sort是一个不错的工具,但它没有足够的功能来分解伪xml,将属性转换为合理的时间值,然后对其进行排序。

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

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

其每行提取一个日期时间;将它们馈送到日期,以将它们转换为自epoch以来的秒数;将每个时间戳粘贴在每行的开头;对粘贴的结果进行数字排序,现在在开始时使用数字时间戳,最后删除时间戳以取回原始文件。

测试:

$ 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>

最新更新