Question

I'm trying to pipe some files from the find command to the interactive remove command, so that I can double check the files I'm removing, but I've run into some trouble.

find -name '#*#' -print0 | xargs -0 rm -i

I thought the above would work, but instead I just get a string of "rm: remove regular file ./some/path/#someFile.js#? rm: remove regular file ./another/path/#anotherFile#?..."

Can someone explain to me what's exactly is happening, and what I can do to get my desired results? Thanks.

Was it helpful?

Solution 2

Can someone explain to me what's exactly is happening,

As the man page for xargs says (under the -a option): "If you use this option, stdin remains unchanged when commands are run. Otherwise, stdin is redirected from /dev/null."

Since you're not using the -a option, each rm -i command that xargs is running gets its stdin from /dev/null (i.e. no input is available). When rm asks whether to remove a particular file, the answer is effectively "no" because /dev/null gives no reply. rm receives an EOF on its input, so it does not remove that file, and goes on to the next file.

and what I can do to get my desired results?

Besides using find -exec as unxnut explained, another way to do it is to use the -o (or --open-tty) option with xargs:

find -name '#*#' -print0 | xargs -0 -o rm -i

That's probably the ideal way, because it allows rm -i to handle interactive confirmation itself, as designed.

Another way is to use the -p (or --interactive) option with xargs:

find -name '#*#' -print0 | xargs -0 -p rm

With this approach, xargs handles the interactive confirmation instead of having rm do it. You may also want to use -n 1, so that each prompt only asks about one file:

find -name '#*#' -print0 | xargs -0 -p -n 1 rm

The advantage of using xargs over find -exec is that you can use it with any command that generates the file path arguments, not just with find.

OTHER TIPS

You can do this by using exec option with find. Use the command

find . -name '#*#' -exec rm -i {} \;

xargs will not work (unless you use options such as -o or -p) because it uses stdin to build commands. Since stdin is already in use, you cannot input the response for query with rm.

you can use this simple command to solve your problem.

find . -name '#*#' -delete
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top