ls to (big airquotes) "bundle" them with grep then rm all found matches in one command...Is this achievable?
Simple issue but I'm not quite sufficient in bash command pipes to fully realize my aspirations. Was hoping to glean if not the command I am searching for then maybe where it is I might brush up on the literature so as to complete my task. Here is my issue + what I've tried thus far: So I have a second hand hard drive and there are some (give the benefit of doubt) abnormalities left behind with their name as the file name that are making it impossible to realize this as now my hard drive. I was able to access the root mountpoint and have found the files I wish to remove with ''' ls -A | grep abcdef ''' is there a way to then pipe the grep'd list to a '''rm -f''' command thereafter because when I try '''ls -A | grep abcdef | rm''' it didn't quite work. After that enormous failure (what are you rm'ing exactly?!) I tried ''' ls -A | grep abcdef <| rm ''' plus many other iterations of similar stock but to no avail. Again I don't necessarily desire the "easy answer" but maybe an exact location where I can get some finite assistance in redirection of output would be great. (Did I answer myself? Would dropping it to the /dev/null afterwards do what I need?... I'll be trying that but some command redirection assistance wouldn't hurt to ask for hopefully) Any help would be much appreciated, thanks.
A pipe (|
) connects a process's standard output stream to another process's standard input stream. You can't use that to pass a list of filenames to rm
directly, because rm
does not read filenames from its standard input.
You could use the xargs
program to read the list on its standard input, and "bundle" the filenames for rm
:
ls -A | grep abcdef | xargs rm
but don't, there are all kinds of problems with this approach - in particular that grep
processes input line-by-line, while xargs
splits inputs on whitespace by default. You could make it better using something like
shopt -s dotglob # simulate ls -A "almost all" hidden files
printf '%s\0' * | grep -z abcdef | xargs -0 rm
which uses the ASCII null character to separate filenames unambiguously. A usually preferred approach is to use the find
command:
find . -maxdepth 1 -name '*abcdef*' # -delete
(I've left the -delete
commented for now - make absolutely sure it is find
ing the right files before uncommenting it, since there's no "undo" operation).
Note that find
recurses into subdirectories by default - if you want the equivalent of ls -R
then remove the -maxdepth 1
. You can add -type f
to find and delete files only (omitting directories).
Also note that find -name
uses shell glob patterns rather than the regular expressions used by grep
(it also has a -regex
match predicate but that doesn't seem to be necessary here).
See also Why not parse ls
(and what to do instead)?