xargs with rm + filename containing spaces
xargs -d "\n" -I {} rm \"{}\"
This assumes GNU coreutils' version of xargs
that supports the -d
option for specifying the delimiter.
This will not work together with your find
command because it adds double quotes to the pathnames found by find
. This means that instead of ./somedir/file.scala
, the call to rm
is done with the literal pathname "./somedir/file.scala"
.
Example:
$ touch hello
$ touch '"hello"'
$ ls
"hello" hello
$ echo hello | xargs -d "\n" -I {} rm \"{}\"
$ ls
hello
It works when you pipe the generated commands to bash
because bash
does quote removal.
It would probably also have worked if you didn't go through the extra effort to add the quotes in the first place:
xargs -d "\n" -I {} rm {}
To delete your files properly, use
find . -type f -name '*.scala' -delete
or, if you still want to use xargs
:
find . -type f -name '*.scala' -print0 | xargs -0 rm
which passes the pathnames between find
and xargs
as a nul-delimited list. Nul (\0
) is the only character that is not allowed in a pathname on Unix systems. Filenames can additionally not contain /
, but newlines are allowed.
A third option would be to call rm
directly from find
:
find . -type f -name '*.scala' -exec rm {} +
Note that {}
does not need to be (and should not be) quoted as find
knows perfectly well how to pass pathnames with spaces (or newlines or whatever it may be) to the named utility.
Related videos on Youtube
LoveWithMaths
Updated on September 18, 2022Comments
-
LoveWithMaths over 1 year
I am writing a simple programs which deletes all the fetched files. Files can contain spaces so I have added quotations as seen below
find -name "*.scala" | xargs -d "\n" -I {} rm \"{}\"
The above fails with error : cannot remove, no such file or dir. But if I list the same files they are there. Also if I do below and use bash to execute it; it works
find -name "*.scala" | xargs -d "\n" -I {} echo rm \"{}\" | bash
Can someone please explain why 1st scenario din't worked?
-
CervEd about 3 yearsif you're using
find
usefind ... -delete
instead. Piping torm
makes no sense
-
-
LoveWithMaths about 6 yearswhat does + do in : find . -type f -name '*.scala' -exec rm {} +
-
Kusalananda about 6 years@linuxuser
-exec rm {} +
would executerm
once with five files, while-exec rm {} \;
would executerm
five times with one file each time. -
LoveWithMaths about 6 yearsbut the above definition is not limited to rm; its how exec argument will work for any command.
-
Kusalananda about 6 years@linuxuser
-exec mv {} /destination +
for example. With GNUmv
, that may be written as-exec mv -t /destination {} +
instead.