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 of
mkshor
dash`):
$ 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.