Score:0

ls to (big airquotes) "bundle" them with grep then rm all found matches in one command...Is this achievable?

in flag

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.

vanadium avatar
cn flag
Try to be less verbose and more to the point. Clearly indicate what your "task" is, i.e., what is your ultimate goal. Consider using code formatting to distinguish the terminal code from the text, which also will help improve readability. Clear, readable questions are more likely to attract clear, readable answers.
guiverc avatar
cn flag
I would write a `find` that finds the files you want, then just add a `-delete` option to that command (ie. let your worked out `find` delete the files it finds) ; but that's not using the piping as you're asking for.
hr flag
It sounds like you're looking for `xargs`... however as noted by @guiverc, `find` would generally be preferred over `ls` + `grep` + (xargs) `rm`
Jake Baldwin avatar
in flag
@vanadium - I thought I did. I'm using a cellular device to do this post and at the bottom of the description box it showed how to do that so I figured it just wasn't showing in my input box. I have some results from grep'd "ls" command I wanted to have be rm'd instead of displayed in a long list.
Jake Baldwin avatar
in flag
@guiverc - I would just "find" them but I was wanting all files with the particular name anywhere in them so I "ls -AR | grep abc" was the best I could come to. If there's a better way with "find" please show me. (No sarcasm)
Jake Baldwin avatar
in flag
@steeldriver - I'll look into it. xargs.... I'll have to read the man page on it, thanks everyone.
guiverc avatar
cn flag
`find` is a command that allows regex's like what you're using (and far more complex)... ie. using the `-name` clause. One good thing with *unix* (posix, or GNU/Linux) is there are many ways anything can be accomplished. That was @vanadium point I believe; tell us what you want to achieve and you may have got many results that achieve what you want (`find -name '*paper*'` will find names of files/folders that contain the word paper (anywhere)... including looking in sub-directories below your current $PWD ... adding a `-delete` to that would cause those files/folders to be deleted
Score:2
hr flag

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 finding 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)?

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.