2

Please advice what is wrong with the following command

find /tmp/dir -name "* *" -type f | rename 's/*/fixed_/g'

remark - I prefer to do that with one command not loop syntax

What I want is to rename all the files under /tmp/dir , by adding the name fixed_ before each file

For example ( the files )

Fevc.txt
Ddve.txt

Should rename to:

fixed_Fevc.txt
fixed_Ddve.txt
  • Does your find command even give output? It is perfectly find to omit -name here. – Bernhard Sep 3 '14 at 7:56
  • 3
    I get from the output - call: rename from to files... ( but files not renamed ) – maihabunash Sep 3 '14 at 7:59
4

Temporary note: there is something wrong - the rename pattern does not handle filenames with path; I'm working on a fix

What is wrong in your command is two things:

find /tmp/dir -name "* *" -type f | rename 's/*/fixed_/g'

  • The -name "* *" matches only file names with a space in it - that's not what you want, right?

    • the solution is to just leave it out; We do not want to exclude files matching some name - we want all.
  • The rename pattern is wrong in two ways

    • you used a shell glob pattern, but it needs to be a regular expression, in short a regex (It can be some general perl expression - let's ignore it and use only s///g)
    • the fixed pattern would match the complete name, and replace it with fixed_. You want to "replace" the "first 0 characters" with fixed_, technically. That's the start of the line, matched with ^. We can leave out the g because there is only one replacement needed per line.

Putting it together, it looks like this:

find /tmp/dir -type f | rename 's/^/fixed_/'

  • +1 for the (overdue) rename 's/^/fixed_/' "correction". The OP clearly has a * in the regex which is indeed highly unsafe, as whenever one wants something to get prepended (like the "fixed_" in this example), one must use /^/ not /*/. – syntaxerror Dec 4 '14 at 12:31
1

It seems your system features the older version of rename that doesn't use regular expressions. You can rename your files with

cd /tmp/dir/
for f in *\ * ; do
    [[ -f $f ]] && mv "$f" fixed_"$f"
done

(untested)

For the rename command with regex support, you have to change the regular expression: * needs something to operate on, it means "repeat the previous thing zero or more times". You don't want to replace anything, you want to prepend, so use ^ which stands for the beginning of the string:

rename 's/^/fixed_/'
1

If anyone's interested in a zsh solution

 cd /tmp/dir
 for f (*(.)) mv $f fixed_$f

where (.) means files only

A simpler case

 for f (*.txt) mv $f fixed_$f

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.