0

I am using xargs and rm with find in order to remove files that follow a specific pattern defined by find as follows.

touch file
find . -name file | xargs rm

Everything works fine with the above code, but if I enter the -i option to rm, then executing:

touch file
find . -name file | xargs rm -i

prints:

rm: remove regular empty file ‘./file7’? user@host:$

without letting me enter y or n ? Thus the file is not removed.

What's the problem in here ?

I also am aware of -p parameter of xargs which works but it is more general. That is, it prompts user to execute the specific command, which is not user-friendly.

EDIT: While using it in a shell script, I've found out that it executes the command I want but it also prints find's result. Something that it is not preferable.

Also when I pass the ls file2 command to cmd variable, it does not specifically print the file2's specs. Same thing happens when I type rm -i file2 . It prompts me to delete every single file in the directory.

This is my script:

#!/bin/bash
touch file{1..9}      # Create 9 files named file1,file2...file9
echo -n 'command: '  # Prompt user
read -e cmd             # read command
find . -exec ${cmd} '{}' +  

The only solution I can think of, is to prompt the user separately for his preferred pattern. Then store that pattern to a variable and pass it as an argument to find command's -name option.

Something like this:

#!/bin/bash
touch file{1..9}     # Create 9 files named file1,file2...file9
echo -n 'command: '  # Prompt user for command
read -e cmd          # read command
echo -n 'pattern: '  # Prompt user for pattern
read -e pattern
find . -name "$pattern" -exec ${cmd} '{}' +  

But even with this solution, find's output is still printed and if the pattern field is left empty (i.e the user just does not want to use a pattern) then problems occur.

Any Ideas ?

0

The problem here is that the stdin (the standard input) for the command ran from xargs (in this case rm) is redirected from /dev/null, and the stdin is the file descriptor used by rm to obtain the user's confirmation.

You could use the -a option so that rm obtain the list of files from an intermediate file previously generated by the find command (the -a option makes xargs to let the stdin untouched), in any case, I understand this may not be what you really want since it requires the intermediate file. A more straight approach similar to what you wanted can be obtained with the command below:

for i in $(find . -name file); do rm -i "$i"; done

2

xargs reads data from stdin. When you use rm -i rm also tries to read the answer from stdin (try touch test && echo y | r -i test ; ls test) but stdin is closed by xargs (I assume) so rm reacts as if you had pressed ctrl-d at the prompt.

Another solution might be find's -exec option:

touch test
find . -name test -exec rm -i {} \;
0
     Just try that command

    find . -type f -iname filename -delete


  it is better to delete the need file.

   -type f ----> specific the file type ( file or directory or etc. )
   -iname  ----> ignore the case sensitive ( test or Test)
   -delete ----> its one of find command option, its delete files  

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.