I have the following files:
$ ls *.png | egrep -i "am|pm"
output-0 11.42.30 AM.png
output-0 5.10.12 PM.png
....
I want to remove them but get this error:
$ ls *.png | egrep -i "am|pm" | while read line; do rm "$line"; done
rm: cannot remove ''$'\033''[0m'$'\033''[01;35moutput-0 11.42.30 AM.png'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;35moutput-0 5.10.12 PM.png'$'\033''[0m': No such file or directory
rm: cannot remove ''$'\033''[01;35moutput-1 11.42.30 AM.png'$'\033''[0m': No such file or directory
What's the problem with my codes?
ls
is risky in scripts and command lines. One problem is what is described in a comment by @PerlDuck, ANSI escape sequences for colour output. I would recommend another approach withfind
Create test files
Check that the
find
command line finds the files that you expect it to findand do it
If you don't want to search into subdirectories, add
-maxdepth 1
Check the result
Files with am, pm, AM, PM in the name should be deleted but
asdf.png
is not deleted.If you really want to use a
while read
loop in that way, then use a shell glob andprintf
with null delimiters e.g.However, there are several ways to get
bash
to expand to a list of the files to be deleted directly - without the need to pipe togrep
andwhile
:using simple shell globs
or - if you don't mind matching a
.PNG
extension as well - making use of thenocaseglob
optionusing extended globs
or
The
--
marks the end of options, just in case there are filenames that begin with a hyphen - you can use a pattern with an explicit directory prefix like./*(am|pm)
instead if you prefer.Add the
-i
or-I
option if you want to review the file names interactively before deletion.