views:

69

answers:

6

I have a folder with files named as

input (1).txt
input (2).txt
input (3).txt
...
input (207).txt

How do I rename them to

input_1.in
input_2.in
input_3.in
...
input_207.in

I am trying this

for f in *.txt ; do mv $f `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done

But it gives me

mv: target `(100).txt' is not a directory
mv: target `(101).txt' is not a directory
mv: target `(102).txt' is not a directory
...

Where did I go wrong?


I have put in the quotes now, but I get this now

mv: `input (90).txt' and `input (90).txt' are the same file

It is somehow trying to rename the file to the same name. How is that happening?

+3  A: 

You're forgetting to quote your arguments.

... mv "$f" "$(echo "$f" | ... )" ; done
Ignacio Vazquez-Abrams
@Ignacio thanks!
Lazer
+2  A: 

That is because bash for split the element with space ' ' so you are commanding it to move 'input' to '(1)'.

The way to solve this is to tell bash to split by new line using IFS variable.

Like this:

IFS=$'\n'

Then do your command.

However, I suggest you to use find to do this instead using -exec command.

For example:

find *.txt -exec mv "{}" `echo "{}" | sed -e 's/input\ (\([0-9]*\))\.txt/input_\1.in/'` \;

NOTE: I write this from memory and I did test this so let try and adjust it.

Hope this helps.

NawaMan
Still this `mv: 'input (90).txt' and 'input (90).txt' are the same file`
Lazer
I don't think you can use '\d' (from what I rememeber), try using '[0-9]'.
NawaMan
Thanks! `[0-9]` worked. Why does `\d` not work?
Lazer
@Lazer: in `sed` the escape `\d` introduces a decimal character representation `\d97` == "a"
Dennis Williamson
thanks @Dennis.
Lazer
+3  A: 

no need to call external commands

#!/bin/bash
shopt -s nullglob
shopt -s extglob
for file in *.txt
do
  newfile="${file//[)]/}"
  newfile="${file// [(]/_}"
  mv "$file" "${newfile%.txt}.in"
done
ghostdog74
A: 
for f in *.txt ; do mv "$f" `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
Omar
A: 

If you have GNU Parallel http://www.gnu.org/software/parallel/ installed you can do this:

seq 1 207 | parallel -q mv 'input ({}).txt' input_{}.in

Watch the intro video for GNU Parallel to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

Ole Tange
+1  A: 

As you've already fixed, you need to quote the $f argument to mv.

As to your second problem, sed doesn't support \d. You could use [0-9] instead.

Brian Campbell