M BUZZ CRAZE NEWS
// news

Running a Bash while loop over all similar files

By Emma Martinez

I would like to write a while loop in Bash that runs over all instances of files that are of the form of

{number}.tst

for example, 1.tst, 2.tst, ... 50.tst.

I do not want it to run over the file tst.tst.

How would I go about writing this? I assume I will need a boolean phrase and [0-9]* somewhere in there, but I am not entirely sure on the syntax.

2

4 Answers

If you only need to exclude alphabetic names like your example tst.tst you could use a simple shell glob

for f in [0-9]*.tst; do echo "$f"; done

With bash extended globs (which should be enabled by default in Ubuntu)

given

$ ls *.tst
1.tst 2.tst 3.tst 4.tst 50.tst 5.tst bar.tst foo.tst

then +([0-9]) means one or more decimal digits:

for f in +([0-9]).tst; do echo "$f"; done
1.tst
2.tst
3.tst
4.tst
50.tst
5.tst

You can check whether extended globbing is enabled using shopt extglob and set it if necessary using shopt -s extglob (and unset using set -u extglob).

5

From this Stack Overflow answer: List files that only have number in names:

find . -regex '.*/[0-9]+\.tst'

OR

Using find also has advantages when you want to do something with the files, e.g. using the built-in -exec, -print0 and pipe to xargs -0 or even (using Bash):

while IFS='' read -r -d '' file
do # ...
done < <(find . -regex '.*/[0-9]+\.tst' -print0)

Note the other answers here my include files that aren't numbers if the filename starts with a digit. The answer posted here does not though. For example:

$ ls *.tst
12tst.tst 1.tst 2.tst
$ find . -maxdepth 1 -regex '.*/[0-9]+\.tst'
./1.tst
./2.tst

NOTE: Use -maxdepth 1 argument to only list numbered files in the current directory and not in sub-directories.

4

In this case, there are no filenames of the form {number}{non-number}.tst, so one possible solution is to include all the filenames that start with a number:

for filename in [0-9]*.tst; do echo "$filename" # Example command
done
4

If you want to process the files in numerical order, there's the seq command (read man seq).

for i in $( seq 1 50 ) ; do echo "Process ${i}.txt"
done
4

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy