I want to delete files, which have size = 0. So I tried:
find ./ -size 0 | xargs rm
But it has a problem with files, which names begin with space.
I found this:
find ./ -size 0 -exec rm -i {} \;
It works. I think my way with xargs
is too sophisticated for this.
What does {} \;
means?
Could you explain me? My English is not very good, so please write simply.
Best Answer
{}
has absolutely no meaning tobash
, so is passed unmodified as an argument to the command executed, herefind
.On the other hand,
;
has a specific meaning tobash
. It is normally used to separate sequential commands when they are on the same command line. Here the backslash in\;
is precisely used to prevent the semicolon to be interpreted as a command separator bybash
and then allow it to be passed as a parameter to the underlying command,find
. Quoting the semicolon, i.e.";"
or';'
, could have been an alternate way to have it stayed unprocessed.The command:
means: find in the current directory (note that the
/
is useless here,.
cannot be but a directory anyway) anything that has a size of 0 and for each object found, run the commandrm -i name
, i.e. interactively prompt for each file if you want to remove it.{}
is replaced by each file name found in the executed command. One nice feature is that this file name is strictly a single argument, whatever the file name (even containing embedded spaces, tabs, line feeds, and whatever characters). This wouldn't be the case withxargs
, unless non portable hacks are used. The final;
is there to end the-exec
clause. The reason why its end needs to be delimited is that otherfind
options might follow the-exec
one, although it is rarely done. e.g.:One issue with this command is that it won't ignore non plain files, so might prompt the user to delete sockets, block and character devices, pipes, and directories. It will always fail with the latter even if you answer yes.
Another issue, although not really critical here, is that
rm
will be called for each file that has a zero size. If you substitute the-exec
ending from/;
to+
,find
will optimize the sub-process creation by only callingrm
the minimal possible number of times, often just once.Here is then how I would modify this command: