我需要在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>
答案 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>