我在使用 bash 的 OSX 中执行此操作,但显然,并非使用所有 bash 约定,因此希望您的建议对我有用:)
我有以下文件
fun bar1.txt
Foo bar2.tXT
(这是一个大写的 XT)fun fun.txt
我的目的是以排序的方式遍历文件列表?
就像是:
for i in (my-sorted-file-list); do
echo $i
done
有什么想法可以做到这一点吗?多谢
答案1
很简单的:
for i in *; do
echo "<$i>"
done
这使用了 bash 的文件通配符。不需要排序,因为 bash 已经对路径名扩展进行了排序。
从man bash
:
Pathname Expansion
After word splitting, unless the -f option has been set, bash scans each word for
the characters *, ?, and [. If one of these characters appears, then the word is
regarded as a pattern, and replaced with an alphabetically sorted list of file
names matching the pattern.
结果示例:
$ touch 'fun bar1.txt' 'Foo bar2.tXT' 'fun fun.txt'
$ for i in *; do echo "<$i>"; done
<Foo bar2.tXT>
<fun bar1.txt>
<fun fun.txt>
请注意,排序顺序取决于LC_COLLATE
(就像sort
实用程序一样)。如果您想要不区分大小写的排序,请使用LC_COLLATE=en_US.utf8
.如果您想要区分大小写的排序,请使用LC_COLLATE=C
。
还man bash
:
LC_COLLATE
This variable determines the collation order used when sorting the results
of pathname expansion, and determines the behavior of range expressions,
equivalence classes, and collating sequences within pathname expansion and
pattern matching.
答案2
要记住一件事:在
for i in *.{txt,py,c}; do ...
首先*.{txt,py,c}
扩展到*.txt *.py *.c
.
虽然*.txt
已排序,*.{txt,py,c}
但未排序。这也意味着如果没有.py
file,您将循环遍历文字 string *.py
。
如果您想要一个排序的全局列表,您应该使用交替通配符而不是大括号扩展。和bash
:
shopt -s extglob
for i in *.@(txt|py|c); do...
排序是否区分大小写取决于区域设置。要在当前区域设置中强制进行不区分大小写的排序,zsh
您可以使用 定义新的排序顺序,例如:
ci() REPLY=${(L)REPLY}
for i (*.(txt|py|c))(N.o+ci)) {...}
答案3
如果没有包含换行符,那么这将为您提供一个排序列表:
_state=$(set +o)
set -f
IFS='
' ; for f in $(set +f; printf %s\\n * |sort) ; do echo "$f" ; done
eval "$_state"
也就是说,它将为您提供当前目录中所有文件的排序列表 - 此处由*
.