Removing files interactively with find and xargs Removing files interactively with find and xargs shell shell

Removing files interactively with find and xargs


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.


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.