Trying to script deleting files from wildcards in a text file
I'm trying to script deleting files whose filenames match wildcards in a text file.
I'm using the following
if [ -z "$1" ]; then
echo -e "Usage: $(basename $0) FILE\n"
exit 1
fi
if [ ! -e "$1" ]; then
echo -e "$1: File doesn't exist.\n"
exit 1
fi
while read -r line; do
[ -n "$line" ] && rm -- "$line"
done < "$1"
in the file list
there are lines
file*
test*
I get the following if i run this
rm: cannot remove ‘file*’: No such file or directory
rm: cannot remove ‘test*’: No such file or directory
I think the * isn't accepted to delete files such as
file 1
file2
file2.txt
test 001 more teskt.txt
Sorry I'm no linux expert. Maybe someone has an easy answer, maybe replace the * with something?
Solution 1:
Pathname expansion happens after variable expansion, but only on unquoted parts of the command line.
rm -- $line # <- no double quotes to expand wildcards
This wouldn't work for filenames containing spaces, as word splitting also happens after variable expansion.
You can use Perl to expand globs:
perl -lne 'unlink glob' -- list.txt
Normal glob needs whitespace backslashed, but you can switch to File::Glob for a different behaviour if it's more convenient to you:
perl -MFile::Glob=:bsd_glob -lne 'unlink glob' -- list.txt
Solution 2:
Find
If you're only deleting files in the pwd (like in the question), you can replace rm
with find -name
like this:
find . -maxdepth 1 -name "$line"
This just outputs filenames that match the glob. If the output looks good, add -delete
at the end.
Python
For anything not covered by the find
solution above, this should work:
python3 -c 'import glob, os, sys; [print(f) for f in glob.glob(sys.argv[1])]' "$line"
If the output looks good, replace print
with os.remove
.
Or you could write the whole script in Python:
#!/usr/bin/env python3
'''
For each line from "fileinput", treat it as a glob and delete
the matching files.
'''
import fileinput
import glob
import os
for line in fileinput.input():
line = line.rstrip('\n')
for file in glob.glob(line):
# If the output looks good, replace "print" with "os.remove"
print(file)
Though note that if no arguments are given, fileinput
reads from stdin instead of erroring.