输入
1 DX
ADA
4 O1
3 I1
C1
2 LA
FTAS
TT66
预期输出
1 DX
ADA
2 LA
FTAS
TT66
3 I1
C1
4 O1
命令
sort -n输入
我尝试按上面提到的数字排序文件。但它也对空值进行了排序,这搞乱了结构。谢谢您的帮助。
答案 0 :(得分: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
答案 1 :(得分:4)
perl -nwe 'if (/^(\d+)/) { $num = $1; } $a[$num] .= $_;
END { print for grep defined, @a }' input.txt
只需使用数组根据找到的行号存储行,如果没有找到数字,则使用最后一个数字。然后打印数组。如果您不使用警告开关-w
,则不需要使用grep defined
,因为警告将在未使用的数组元素上(在这种情况下为0)。
如果行号重复,它会将行附加到前面的条目,这样很方便。它也不需要任何类型的排序,因为数组元素已经排序。
答案 2 :(得分: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
答案 3 :(得分:0)
我不相信你可以单独使用sort
,我会用sed
或类似方法处理它,并将其传输到sort
然后再回来。