3

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?

6 Answers 6

3

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Still this mv: 'input (90).txt' and 'input (90).txt' are the same file
I don't think you can use '\d' (from what I rememeber), try using '[0-9]'.
@Lazer: in sed the escape \d introduces a decimal character representation \d97 == "a"
3

You're forgetting to quote your arguments.

... mv "$f" "$(echo "$f" | ... )" ; done

Comments

3

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

Comments

1

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.

Comments

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

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.