如何迭代带有已排序空格(不区分大小写)的文件列表?

如何迭代带有已排序空格(不区分大小写)的文件列表?

我在使用 bash 的 OSX 中执行此操作,但显然,并非使用所有 bash 约定,因此希望您的建议对我有用:)

我有以下文件

  1. fun bar1.txt
  2. Foo bar2.tXT(这是一个大写的 XT)
  3. 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}但未排序。这也意味着如果没有.pyfile,您将循环遍历文字 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"

也就是说,它将为您提供当前目录中所有文件的排序列表 - 此处由*.

相关内容