3

The rename command in Ubuntu 12.04 (manpage says it's part of perl v5.14.2 2012-03-23) works well in a single directory, but I want to use it on subdirectories too (or, more generally, on a list of files that is the output of another command, via backquotes). For example, I'd expect

rename "s/ /-/g"  `find .`

to change all spaces to dashes in all filenames below the current dir. But this command does nothing.

(Edit: changed rename -n to rename. That option's good for safely experimenting, but only a distraction here.)

The backquotes are not at fault, because replacing find . with e.g. echo */* works.

First doing find . > foo, and then replacing find . with cat foo, does nothing.

Even collapsing the list of files into one line, by replacing find . with find . | tr -d '\n', does nothing.

Which element is at fault?

1 Answer 1

2

This will not work:

rename 's/ /-/g'  `find .`

After running the find command, the shell does word splitting on the results. Consequently, no file name with spaces survives in tact: it is split up into pieces.

You can avoid this by using:

rename 's/ /-/g'  */*

In this form of the command, the shell does not do word splitting and your rename will succeed. This form works even for file names with spaces, tabs, or any other difficult characters.

Alternatively, use find's -exec:

find . -name '* *' -exec rename 's/ /-/g' {} +

This form will work with file names having spaces, tabs, or any other difficult characters.

Demonstration

To see what goes wrong, let's create a file with spaces

$ touch "a b c"
$ find .
.
./a b c

To clarify what goes on, let's create a function to put each argument it sees inside double quotes and display it:

$ display() { printf '"%s"\n' "$@"; }

Now, we can use display to see what happens when we run find .:

$ display `find .`
"."
"./a"
"b"
"c"

This shows word splitting in action. The file name a b c was split into three separate words.

4
  • "in tact": I see what you did there :-) Oct 7, 2014 at 19:57
  • Whitespace in filenames is just one example: a better one might be s/png/jpg/. So this general answer reduces to the workaround of replacing backquotes with find ... -exec rename ..., or find ... | xargs rename .... So I still wonder why backquotes fail. Oct 7, 2014 at 20:06
  • @CamilleGoudeseune "So I still wonder why backquotes fail." It does not have anything to do with which substitute command is used. It is because filenames with white space on the command line are subject to word splitting. Otherwise, it works.
    – John1024
    Oct 7, 2014 at 21:07
  • Correct. Whitespace in filenames is the only problem, after all. I made a better test case from scratch, and, yes, backquotes work. Sorry for wasting your time. Oct 8, 2014 at 20:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .