如何使用linux命令进行排序,同时将3行视为1个块并根据每个块的第一行进行排序

时间:2013-04-19 23:06:38

标签: linux sorting

如何使用linux命令进行排序,同时将3行视为1个块并根据每个块的第一行进行排序?

我知道我可以将3行连接成1行然后排序。但是文件太大了,我不想为了排序而生成临时文件。

2 个答案:

答案 0 :(得分:3)

sort文本文件的行进行排序,其中记录始终由换行符分隔。作为例外,它还支持\0作为记录分隔符,但无法更改记录分离的逻辑

您可以利用上述异常来实现 decorate-sort-undecorate 模式,如下所示:

chunk | sort -z -t'
' -k1 | unchunk

chunk将每三行合并为line1\0line2\0line3\n,以允许sort -z将三行块作为单个记录,并-t'\n' -k1按第一个字段排序在记录中。 unchunk只需将所有\0更改回\n

在Perl中表示,chunk看起来像这样:

perl -pe 'chomp;$_.=($.%3)?"\n":"\0"'

(类似的咒语可以很容易地写在awksed中,而C版本也不会更长。)

unchunk不超过tr '\0' '\n'。因此完整的排序是:

perl -pe 'chomp;$_.=($.%3)?"\n":"\0"' | sort -z -t'
' -k1 | tr '\0' '\n'

给出

的输入文件
b
2nd b line
bla 3rd b line
a
some a line
other a line
x
first x line
other x line

......以上管道产生:

a
some a line
other a line
b
2nd b line
bla 3rd b line
x
first x line
other x line

答案 1 :(得分:0)

以下单行代表在bash中完成工作。它只是将数据读入一个三元组的perl数组,在第一行排序,然后打印所有内容。

您可以轻松地将排序谓词更改为例如按数字排序(使用<=>)或以您想要的任何其他方式排序。这个使用词典顺序。

要使其在Windows中运行,只需切换引号:在外部使用“”,在内部使用“”。

$ perl -e 'while(<>){push@a,[$_,scalar<>,scalar<>]}for(sort{$a->[0]cmp$b->[0]}@a){print join"",@$_}' < foo.txt

这假设输入在foo.txt

实际上我刚刚意识到你可以连接而不是使用内部数组。结果更短!

$ perl -e 'while(<>){push@a,$_.scalar<>.scalar<>}for(sort @a){print}' < foo.txt