如何让Shell脚本按数字顺序遍历文件夹中的文件?
解决Shell遍历文件按数字顺序而非字典序的问题
这个问题很常见——Shell默认的文件名扩展是按字典序排序,所以会出现1.txt之后直接跳到10.txt的情况。这里有几种实用的解决方法,根据你的场景选择:
方法1:直接按数字范围循环(最适合你的连续文件名场景)
既然你明确知道文件是1.txt到15.txt,最直接的方式就是循环数字,然后拼接成对应的文件名。这样完全能保证数字顺序,还能跳过可能不存在的文件:
for i in {1..15}; do solution_file=".solutions/$i.txt" testcase_file="./testcases/$i.txt" # 确保两个文件都存在再处理 if [ -f "$solution_file" ] && [ -f "$testcase_file" ]; then echo "test case $i.txt:" cat "$testcase_file" echo echo "result:" cat "$solution_file" echo echo fi done
方法2:用sort -V进行自然排序(通用场景)
如果你的文件数量不确定,或者存在缺失的数字(比如缺少5.txt),可以先获取所有文件名,再用sort -V进行自然数字排序(它会识别文件名里的数字部分,按数值大小排序):
# 获取所有txt文件并按自然排序 sorted_files=$(ls .solutions/*.txt | sort -V) for file in $sorted_files; do if [ -f "$file" ]; then filename="${file##*/}" echo "test case $filename:" cat "./testcases/$filename" echo echo "result:" cat "$file" echo echo fi done
方法3:结合find和sort -V(更安全的文件处理)
如果担心文件名中有特殊字符(比如空格,虽然你的场景里没有),可以用find配合while read来处理,避免意外:
find .solutions -maxdepth 1 -type f -name "*.txt" | sort -V | while read -r file; do filename="${file##*/}" echo "test case $filename:" cat "./testcases/$filename" echo echo "result:" cat "$file" echo echo done
小提示
sort -V是GNU sort的特性,大部分Linux发行版都支持;如果是BSD系统(比如macOS),可以用sort -n -k1.1,1.来实现类似效果。- 方法1的优势是性能最好,因为不需要额外的排序步骤,适合你这种连续编号的场景。
内容的提问来源于stack exchange,提问作者Nanoboss
相关产品推荐
相关产品推荐

