我正在寻找 Solaris 中的“sort -z”(仅在 GNU 中支持)等效项,这样我就可以获得多行“块”支持。我想按时间顺序(日期然后时间)对一些文本进行排序,并且排序不会破坏该过程中的文本块。
例如,我有:
2020-05-15:02:00:00:000 INFO[LF]
2020-05-15:02:00:02:000 INFO[LF]
[HT]some extra data as second line[LF]
[HT]2020-05-15:02:00:01:000 INFO[LF]
[HT]some extra data as second line[LF]
[HT]some extra data as third line[LF]
2020-05-15:02:00:04:000 INFO[LF]
2020-05-15:02:00:03:000 INFO[LF]
- [HT] 是水平 Tab 键,[LF] 是 \n
我希望将其分类为
2020-05-15:02:00:00:000 INFO[LF]
2020-05-15:02:00:01:000 INFO[LF]
[HT]extra data as second line[LF]
[HT]some extra data as third line[LF]
2020-05-15:02:00:02:000 INFO[LF]
[HT]extra data as second line[LF]
2020-05-15:02:00:03:000 INFO[LF]
2020-05-15:02:00:04:000 INFO[LF]
在 Centos/ubuntu (GNU) 上,我设法做到这一点: sort -zt : -k2,2 -k3,3n -k4,4n -k5,5n -k6,6n (尽管不确定 milisec 是否排序正确)。
请注意:
- 我无法使用 msort - awk / sed / perl 单行解决方案受到欢迎。
- 每行都以 LF 结尾,无论是否为多行。
- 多行(包括前面的第二行)以 HF“tab”字符开头。
谢谢 :-)
答案1
和perl
:
perl -0777 -ne 'print sort /^\d.*\n(?:\D.*\n)*/gm' your-file
将整个文件加载到内存中(使用 slurp 模式-0777 -p
),根据正则表达式提取块(以数字 ( ^
) 开头的行(以数字 ( ) 开头的行,后面是以非数字 ( ) 开头的\d
0 或更多 ( ) 行),然后将它们保存在内存中) ing。*
\D
print
sort
答案2
要对以空分隔的记录进行排序,如果有一个字符保证不会出现在数据中,则可以使用tr
空字节来交换它。然而,这不会直接帮助你,因为你的数据是由换行符分隔的,甚至 GNU 排序也没有选项只将某些换行符视为分隔符。您需要将换行符序列翻译为不包含换行符的内容,然后排序,然后撤消原始翻译。
假设您的数据除了某些行开头的单个制表符之外不包含制表符,则翻译可以是删除制表符之前的换行符,并在排序后将它们添加回来。
awk '/^\t/ {line = line $0; next}
{print line; line = $0}
END {print line}' |
sort |
awk '{gsub(/\t/, "\n\t"); print}'