“文件输入”按数字而不是按字母顺序?

“文件输入”按数字而不是按字母顺序?

我有一个脚本根据文件夹中的每个文件生成索引。所有文件名都是带有扩展名的数字。

如何修改循环以按数字顺序处理它们?

for file in xml/*.xml; do
  ...
done

答案1

如果您可以GNU sort选择对分隔符进行取消限制,\0则可以执行此操作。这样while循环将开始按排序顺序获取文件供您处理。printf用您自己的自定义逻辑替换该选项。

shopt -s nullglob

printf '%s\0' xml/*.xml | sort -zV | while read -rd '' file; do
    printf "%s\n" "$file"
done

shopt -u nullglob

nullglob选项是为了防止 shellxml在当前文件夹中找不到文件时扩展空 glob。该选项-u会在处理完成后取消设置。


作为托尼·斯佩特正确地指出,如果您不想弄乱 shell 选项(例如,它可能因其他原因而启用),您可以在子 shell 中设置并让 glob 扩展发生

( shopt -s nullglob; printf '%s\0' xml/*.xml ) | sort -zV |  while read -rd '' file; do
    printf "%s\n" "$file"
done

答案2

如果可以使用zsh(对于脚本来说,是方便开发和方便部署之间的权衡):

for file in xml/*.xml(n); do
  ...
done

全局限定符 n指定在对 glob 模式的匹配进行排序时,数字序列必须根据它们所表示的整数的数字顺序进行排序,而不是按字典顺序排序,即foo10bar位于 之后foo9bar

您还可以使用setopt numeric_glob_sort使所有 glob 模式都使用此设置。

答案3

沿着库萨罗南达的建议之一

准备:

mkdir xml && cd xml
touch 1.xml 10.xml 23.xml 999.xml
cd ..

环形:

for f in {1..100}; do [ -f "xml/$f.xml" ] && echo process "xml/$f.xml"; done

结果是:

process xml/1.xml
process xml/10.xml
process xml/23.xml

使大括号扩展循环足够大以覆盖最大的数字文件。

答案4

ls -Q xml*.xml | while read line;do 
   ...
done

ls 将按数字顺序列出文件,-Q 将确保处理所有空格。

相关内容