我有一堆从log1log164的文件。

我试图在UNIX终端中列出目录(已排序),但sort函数仅提供如下格式:

home:logs Home$ ls -1 | sort
log1.gz
log10.gz
log100.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz
...etc


我想要的是什么

home:logs Home$ ls -1 | sort
log1.gz
log2.gz
log3.gz
log4.gz
log5.gz
log6.gz
log7.gz
...{more here}
log99.gz
log100.gz
log101.gz
log102.gz
...etc


我有什么建议可以用来做这个?

评论

这绝对是一个编程问题,不应仅仅因为答案涉及低级的外壳编程语言而就不应该迁移!!

如果您事先知道它们分别通过log164.gz命名为log1.gz,那么您甚至需要对它们进行-1命令?

@ruakh ls -1将结果显示在一栏中,而不是整个

@Rabiani:我知道ls -1的作用:它列出了文件名。因为您已经知道文件名,所以我不明白您需要什么文件名。但是既然您已经接受了Kevin的回答,我现在知道:您不需要它。这更有意义。 :-)

#1 楼

bash的括号{}将按以下顺序枚举:

for file in log{1..164}.gz; do
    process "$file"
done


#2 楼

为什么不为这种特殊情况使用内置的ls功能:

-v natural sort of (version) numbers within text

例如ls -1v log*

评论


在BSD / OSX上,此选项是其他选项:-v-强制未经编辑地打印非图形字符。

– Kenorb
2015年2月26日在17:33



这应该是最好的答案。

– 32r34wgf3e
17-10-23在17:11

对于MacOS,它将起作用,找不到如上所述的选项,只有ls |排序-n

– Ricky Levi
18年8月25日在12:31

不要在MacOS上使用。

–mrgloom
19年4月17日在13:42

要在MacOS上执行此操作。安装coreutils:brew install coreutils并将它们添加到路径PATH =“ / usr / local / opt / coreutils / libexec / gnubin:$ PATH”(或仅使用g前缀:gls -lv)

–zbstof
20-2-27在13:32

#3 楼

使用GNU ls(即在Linux,Cygwin或其他专门安装了GNU ls的系统上):

ls -v


在其他Shell中:

echo *(n)


如果希望每个文件名都在单独的行中,请用echo替换printf '%s\n'

如果您还需要文件元数据(ls -l)并且没有GNU ls,则需要为要按词典顺序查看的每个文件名或文件名组分别调用ls。 >
echo log?.gz log??.gz log???.gz


为避免这些困难,请在文件名中使用足够的前导零,以便词典排序对人类友好(log001.gz等)。

#4 楼

尽管在特定情况下解决方案ls -1v当然是最好的,但我认为也可以像原始问题中那样使用与sort一起使用的解决方案,因为这在您的输入并非来自ls时也可以使用。在这种情况下,您可以使用:

ls -1 | sort -n -k1.4


-n选项指示sort进行数字排序,而-k 1.4将sort键设置为第一个字段(即第一个字段中的整个文件名)这种情况)从第四个字符到最后一个字符。

评论


在我的情况下,ls -1 | sort -n -k1.4不起作用。它首先给出未排序的字符,最多4个字符,然后在第4个字符后排序。我用ls -1 | sort |排序-n -k1.4相反,它运行良好。

–布拉布
2014年9月12日于20:53

@Prabhu,相反,您可以对-k1.1,1.3 -k1.4n进行排序。排序实现不一定要稳定,因此您的方法不适用于所有实现。另请参见GNU和FreeBSD排序的-V选项。

–StéphaneChazelas
15年5月26日在11:11

#5 楼

GNU sort(在Linux上可用)具有“版本排序”模式,可以按照您要求的方式解释非数字中的数字:

man 1 sort中获取:


    -V, --version-sort
           natural sort of (version) numbers within text



(创建要列出的空测试文件:touch log1.gz log2.gz log3.gz log99.gz log100.gz log101.gz log102.gz

您的示例案例,添加-V选项(或--version-sort):

ls -1 log*.gz | sort -V
log1.gz
log2.gz
log3.gz
log99.gz
log100.gz
log101.gz
log102.gz


#6 楼

如果您使用Mac或BSD,请尝试以下操作:

ls -1 *.jpg | sort -n


#7 楼

我的Solaris版本不支持ls -v(grrr)。而且上面提供的排序解决方案1)需要知道文件名中数字的位置,并且2)无法处理多部分版本号之类的事情。

以下方法与Solaris兼容,不需要预先知道数字的位置,并处理包含2、3或4个组成部分的版本号(例如:a-1.2,foo-5.6.7,bar_baz_9.10.11.12)。它还使用sort -f将大写和小写折叠在一起,并正确处理与文件混合在一起的目录:



如果您的目标操作系统支持ls -d | sort -f -t . -k 1,1 -k 2,2n -k 3,3n -k 4,4n,那显然是更好的解决方案。

#8 楼

Perl解决方案:

ls log*.gz | perl -ne 'sub getnum{ $_[0] =~ /log(\d+)\.gz/;  }; push @A, $_; END{ print sort { getnum $a <=> $b } @A}'


#9 楼

$ ls
log101.gz  log102.gz  log103.gz  log104.gz  log105.gz  log106.gz  log10.gz  log1.gz
$ ls | sort -t . -n -k1.4
log1.gz
log10.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz


评论


-t。这里是多余的。

–StéphaneChazelas
15年5月26日在11:15

#10 楼



我有文件1.jpg 2.jpg ... 18.jpg

$ echo *.jpg | tr -s ' ' '\n' | sort -n

sortls输出,因为无法打印颜色字符。如果您尝试以下操作:

ls -1 --color=none *.jpg | sort -n

它将很好地工作。我不知道为什么。

但是您总是可以像这样剥离颜色,sort可以工作: -i将为此提供一个选项。

#11 楼

命令:

ls -l | sort --human-numeric-sort


评论


请使用正确的语法并说明您的命令应产生的结果

–mattia.b89
20年5月1日在20:21