首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Bash - numerical排序将10排在1之前

Bash - numerical排序将10排在1之前
EN

Stack Overflow用户
提问于 2012-03-31 20:26:31
回答 3查看 1.8K关注 0票数 2

我在一个目录里。有两个子目录,我想按数字顺序列出其中的文件。在第一个目录中,文件名为01,02,03...而且它们排序得很好。但是在第二个目录中,文件被命名为1,2,3,因此在1之前的10个排序。键控似乎不起作用,因为我是从文件返回的目录,所以像这样的脚本:

代码语言:javascript
复制
find "$PWD" -type f|sort -n -t _ -k 1

不起作用。如何以真正的数字顺序列出?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-31 22:18:38

排序手册:Sort numerically: the number begins each line ...我怀疑find的输出会是这样的。因此,您应该编写一个脚本,将文件名中的前导字符去掉,然后调用sort。

例如,find "$WORD" -type f | cut -d / -f 2-将对第一级目录中的文件名进行数字排序,但其余的不会作为数字排序。

您必须根据自己的需要编写脚本,但如果您要查找的内容位于单个目录中,则可以使用上面的代码行。

票数 2
EN

Stack Overflow用户

发布于 2012-03-31 21:01:01

你提出了一个有趣的挑战。试试这个Perl脚本:

代码语言:javascript
复制
#!/usr/bin/perl
use warnings;
use strict;
use integer;

# This script sorts filenames while respecting their ordinal component,
# outputting 'dir/stem9.ext' before 'dir/stem10.ext'.  As input, it
# expects one filename per line on stdin.

our $n_digits = 6;

sub compare_filenames_ordinally ($$) {
    my ($a, $b) = @_;
    my $pattern = qr|^(.*?)(\d*)((?:\.[^/\d]*)?)$|;
    my ($stem_a, $ordinal_a, $extension_a) = $a =~ /$pattern/;
    my ($stem_b, $ordinal_b, $extension_b) = $b =~ /$pattern/;
    length($ordinal_a) <= $n_digits && length($ordinal_b) <= $n_digits
      or die "$0: the ordinal part of the filename "
      . "is longer than $n_digits digits\n";
    my $ordinal_a1 = length($ordinal_a)
      ? sprintf "%0${n_digits}d", $ordinal_a : '';
    my $ordinal_b1 = length($ordinal_b)
      ? sprintf "%0${n_digits}d", $ordinal_b : '';
    my $a1 = "${stem_a}${ordinal_a1}${extension_a}";
    my $b1 = "${stem_b}${ordinal_b1}${extension_b}";
    return $a1 cmp $b1;
}

my @file = <>;
chomp for @file;
@file = sort { compare_filenames_ordinally $a, $b } @file;
print "$_\n" for @file;

这个脚本无疑是可以改进的,尤其是因为它针对$a$b重复了一些代码行,但它的想法是在将其与其他文件名进行比较之前,将类似于dir/stem10.txt的内容扩展为dir/stem000010.txt。

票数 0
EN

Stack Overflow用户

发布于 2012-04-01 00:01:42

这可能对你有用:

代码语言:javascript
复制
mkdir test
cd test
mkdir t1 t2
cd t1
seq -f 'test_%02g.txt 20 | xargs touch
cd ../t2
touch test_{1..20}.txt
cd ..
find . -type f | sort -t_ -k1,1 -k2,2g
./t1/test_01.txt
./t1/test_02.txt
./t1/test_03.txt
./t1/test_04.txt
./t1/test_05.txt
./t1/test_06.txt
./t1/test_07.txt
./t1/test_08.txt
./t1/test_09.txt
./t1/test_10.txt
./t1/test_11.txt
./t1/test_12.txt
./t1/test_13.txt
./t1/test_14.txt
./t1/test_15.txt
./t1/test_16.txt
./t1/test_17.txt
./t1/test_19.txt
./t1/test_20.txt
./t2/test_1.txt
./t2/test_2.txt
./t2/test_3.txt
./t2/test_4.txt
./t2/test_5.txt
./t2/test_6.txt
./t2/test_7.txt
./t2/test_8.txt
./t2/test_9.txt
./t2/test_10.txt
./t2/test_11.txt
./t2/test_12.txt
./t2/test_13.txt
./t2/test_14.txt
./t2/test_15.txt
./t2/test_16.txt
./t2/test_17.txt
./t2/test_18.txt
./t2/test_19.txt
./t2/test_20.txt

或者这样:

代码语言:javascript
复制
find . -type f | 
sed 'h;s/.*\//& /;H;s/.* //;s/[^0-9]//g;x;G;s/\n/ /g' |
sort -k2,2 -k4,4g |
cut -d' ' -f1
./t1/test_01.txt
./t1/test_02.txt
./t1/test_03.txt
./t1/test_04.txt
./t1/test_05.txt
./t1/test_06.txt
./t1/test_07.txt
./t1/test_08.txt
./t1/test_09.txt
./t1/test_10.txt
./t1/test_11.txt
./t1/test_12.txt
./t1/test_13.txt
./t1/test_14.txt
./t1/test_15.txt
./t1/test_16.txt
./t1/test_17.txt
./t1/test_19.txt
./t1/test_20.txt
./t2/test_1.txt
./t2/test_2.txt
./t2/test_3.txt
./t2/test_4.txt
./t2/test_5.txt
./t2/test_6.txt
./t2/test_7.txt
./t2/test_8.txt
./t2/test_9.txt
./t2/test_10.txt
./t2/test_11.txt
./t2/test_12.txt
./t2/test_13.txt
./t2/test_14.txt
./t2/test_15.txt
./t2/test_16.txt
./t2/test_17.txt
./t2/test_18.txt
./t2/test_19.txt
./t2/test_20.txt
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9955843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档