How to 'rm' or 'mv' a range of files such as file01.txt, file02.txt...file85.txt

Solution 1:

You need to use brace expansion of bash:

rm file{08..13}.txt

This will remove files file08 to file13, will show an error message if any file is missing.

Set the range to meet your need.


The problem with the globbing operator [] is that it treats each character/digit inside it as a single token and so only supports range declaration using single digits.

If you insist on using [], you can use this rather ugly pattern to match file08 to file13:

rm file0[8-9].txt file1[0-3].txt

Solution 2:

Some shells, such as Ubuntu's default /bin/sh ( which is dash ) or mksh don't have brace expansion, or in case of ksh - brace expansion can't use padded zeroes :

$ ksh -c 'echo {05..13}'
5 6 7 8 9 10 11 12 13

In such cases, we can make use of printf to format the number portion of the filename, and use a while loop to implement c-like for loop behavior (note to replace echo with rm or whatever you want):

$ i=5; while [ "$i" -le 10 ]; do num=$(printf "%.2d" "$i" ); echo "file$num.txt";i=$(($i+1)); done
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

And this is fairly portable - works with dash, ksh, mksh, also bash. In the case of ksh and bash we can also use c-style for loop syntax (but not in case ofmkshordash`):

$ ksh -c 'for((i=5;i<11;i++)); do num=$(printf "%.2d" "$i" ); echo "file$num.txt";done'             
file05.txt
file06.txt
file07.txt
file08.txt
file09.txt
file10.txt

Note that in bash's case, printf supports printing to variable, and thus we could do printf -v num "%.2d" "$i" instead of using command substitution.