Nanoboss
Nanoboss

Reputation: 313

Shell script to loop over all files in a folder and pick them in numerical order

I have the following code to loop through the files of a folder. Files are named 1.txt, 2.txt all the way to 15.txt

for file in .solutions/*; do 
    if [ -f "$file" ]; then 
        echo "test case ${file##*/}:"
        cat ./testcases/${file##*/}
        echo
        echo "result:"
        cat "$file"
        echo
        echo
    fi 
done

My issue I get 1.txt then 10.txt to 15.txt displayed.

I would like it to be displayed in numerical order instead of lexicographical order, in other words I want the loop to iterate though the files in numerical order. Is there any way to achieve this?

Upvotes: 0

Views: 299

Answers (2)

Dabombber
Dabombber

Reputation: 466

Looping through ls is usually a bad idea since file names can have newlines in them. Redirecting using process substitution instead of piping the results will keep the scope the same (variables you set will stay after the loop).

#!/usr/bin/env bash

while IFS= read -r -d '' file; do
    echo "test case ${file##*/}:"
    cat ./testcases/${file##*/}
    echo
    echo "result:"
    cat "$file"
    echo
    echo
done < <(find '.solutions/' -name '*.txt' -type f -print0 | sort -nz)

Setting IFS to "" keeps the leading/trailing spaces, -r to stop backslashes messing stuff up, and -d '' to use NUL instead of newlines.

The find command looks normal files -type f, so the if [ -f "$file" ] check isn't needed. It finds -name '*.txt' files in '.solutions/' and prints them -print0 NUL terminated.

The sort command accepts NUL terminated strings with the -z option, and sorts them numerically with -n.

Upvotes: 1

Mihir Luthra
Mihir Luthra

Reputation: 6769

ls *.txt | sort -n

This would solve the problem, provided .solutions is a directory and no directory is named with an extension .txt.

and if you want complete accuracy,

ls -al *.txt | awk '$0 ~ /^-/ {print $9}' | sort -n

Update:

As per your edits, you can simply do this,

ls | sort -n |
    while read file
    do
        #do whatever you want here
        :
    done

Upvotes: 1

Related Questions