Removing files with rm using find and xargs
Asked Answered
C

5

32

When I do

rm file.txt

or

rm *.txt

I'm prompted for each file, since I didn't specify the -f option to rm.

But when I do this:

find . -type f -name '*.txt' | xargs rm

the files are removed without the confirmation.

What is the logics behind this? Is it possible to find the reason in some documentation? I cannot explain why this would be the case.

Cutworm answered 16/3, 2017 at 7:43 Comment(2)
The behaviour you describe is that of 'rm -i'. Do you have an alias set in you shell for the rm command? Does 'alias rm' give any output?Whitewing
alias rm gives the output rm -i, so that explains it. ThanksCutworm
W
35

You have an alias set for the rm command to 'rm -i'. Therefore if you invoke the command directly as in

rm file.txt

or

rm *.txt

the alias will be expanded. If you will call it with xargs as in

find . -type f -name '*.txt' | xargs rm

The rm is passed as a simple string argument to xargs and is later invoked by xargs without alias substitution of the shell. You alias is probably defined in ~/.bashrc, in case you want to remove it.

Whitewing answered 16/3, 2017 at 7:52 Comment(3)
This relies on spaces in file names... careful. Use print0 instead. https://mcmap.net/q/454496/-removing-files-interactively-with-find-and-xargsDisequilibrium
DON"T USE COMMANDS FROM THIS ANSWER. This commands are unsafe for space containing filenames. Use find -execTomika
For example, if you have two files (config file.txt and config) then find . -type f -name '*.txt' | xargs rm will delete config file but not config file.txt file.Tomika
K
27

you can use this simple command to solve your problem

find . -type f -name '*.txt' -delete
Katlaps answered 27/10, 2021 at 11:7 Comment(1)
Nice, but there's a typo, it should be -type, not --type, otherwise this solution worked well for meAhq
B
2

Depending on your version of xargs you may have the --no-run-if-empty GNU extension option available to you:

find . -type f -name '*.txt' | xargs  --no-run-if-empty  rm -rf
Blooded answered 4/8, 2020 at 11:46 Comment(1)
I know the question is about Linux, but if you are a Mac user like me, this option is implicit and is not needed.Desperado
U
0
ls "fnames with wild chars" | xargs -I{} rm -v {}

Here -I{} is used to replace all inputs be substituted in place of {}.

NOTE: It can be catastrophic to use names with improper wildcards as a file that is removed cannot be retrieved. Use it with caution and try to refrain from using recursive(-r) flag.

Upon answered 6/4 at 18:45 Comment(0)
M
-1

You want to remove into PATH_DIR1 existing files in PATH_DIR2 :

find PATH_DIR1 -type f  -exec basename '{}' ';' | xargs printf -- 'PATH_DIR2/%s\n' | xargs rm

Explanations :

  1. List all filenames in PATH_DIR1

find PATH_DIR1 -type f -exec basename '{}' ';'

  1. Filter the previous listing with the existing files in PATH_DIR2 (find the intersect data)

xargs printf -- 'PATH_DIR2/%s\n'

  1. Execute the remove action to the filtered result

xargs rm

Monumental answered 10/11, 2023 at 15:58 Comment(1)
Is there any advantage to this approach over the others? Also, can you add an explanation of the commands?Swartz

© 2022 - 2024 — McMap. All rights reserved.