我有一个脚本根据文件夹中的每个文件生成索引。所有文件名都是带有扩展名的数字。
如何修改循环以按数字顺序处理它们?
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 将确保处理所有空格。