1

输入

1   DX
    ADA
4   O1
3   I1
    C1
2   LA
    FTAS
    TT66

预期产出

1   DX
    ADA
2   LA
    FTAS
    TT66
3   I1
    C1
4   O1

命令

排序 -n 输入

我尝试如上所述对文件进行数字排序。但它也对空值进行了排序,这弄乱了结构。谢谢您的帮助。

4

4 回答 4

6

好吧,您需要将未编号的行视为属于编号的行。假设 '%' 符号没有出现在输入中,那么这样的解决方案呢?

dtpwmbp:~ pwadas$ cat bzz.txt 
1   DX
    ADA
4   O1
3   I1
    C1
2   LA
    FTAS
    TT66
dtpwmbp:~ pwadas$ cat bzz.txt |perl -0pe 's/\n /%/g'
1   DX%   ADA
4   O1
3   I1%   C1
2   LA%   FTAS%   TT66
dtpwmbp:~ pwadas$ cat bzz.txt |perl -0pe 's/\n /%/g' | sort -n |perl -0pe 's/%/\n /g' 
1   DX
    ADA
2   LA
    FTAS
    TT66
3   I1
    C1
4   O1
dtpwmbp:~ pwadas$ 

在此解决方案中,首先删除换行符,以保持非编号分配为一个编号,然后在排序后,换行符被带回其原始位置,因此输出看起来像只有编号的那些被排序。AFAIR 这称为“多行模式”匹配。我不确定是否应该将其移至 superuser.com

于 2013-04-07T14:08:34.067 回答
4
perl -nwe 'if (/^(\d+)/) { $num = $1; } $a[$num] .= $_; 
           END { print for grep defined, @a }' input.txt

只需使用数组根据找到的行号存储行,如果没有找到数字,则使用最后一个数字。然后打印数组。如果您不使用警告开关-w,则不需要使用grep defined,因为警告将出现在未使用的数组元素上(在这种情况下为 0)。

在重复行号的情况下,它会将行附加到以前的条目中,这很方便。它也不需要任何排序,因为数组元素已经排序。

于 2013-04-07T14:38:31.890 回答
1

此输出跟踪最新的初始数字,并将当前行附加到散列的适当元素上。散列中的数据按键的数字顺序输出。

use strict;
use warnings;

my $n;
my %data;
while (<DATA>) {
  $n = $1 if /^(\d+)/;
  $data{$n} .= $_ if $n;
}

print $_ for map $data{$_}, sort { $a <=> $b } keys %data;

__DATA__
1   DX
    ADA
4   O1
3   I1
    C1
2   LA
    FTAS
    TT66

输出

1   DX
    ADA
2   LA
    FTAS
    TT66
3   I1
    C1
4   O1

更新

您可能更喜欢这种替代方法,它读取整个文件,在每个后跟一个数字的换行符之后将其拆分,并按照初始数字的数字顺序对这些记录进行排序。输出与之前的解决方案相同。

use strict;
use warnings;

local $/;
print for sort {
  my ($aa, $bb) = map /^(\d+)/, $a, $b;
  $aa <=> $bb;
} split /(?<=\n)(?=\d)/, <DATA>;

__DATA__
1   DX
    ADA
4   O1
3   I1
    C1
2   LA
    FTAS
    TT66
于 2013-04-07T15:05:12.687 回答
0

我不相信你可以sort单独使用,我会用sed或类似的方式处理它,sort然后再次输入和返回。

于 2013-04-07T14:05:59.553 回答