2

我需要在 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=;使用第三列作为排序列 => -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>
4

2 回答 2

4

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

例子:

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

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

于 2013-07-24T20:33:02.787 回答
2

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>
于 2013-07-24T20:34:33.233 回答