Batch rename using shell script

I have a folder with files named

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

How to rename them to

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

I'm 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 am I wrong?


Now I have added quotes, but now I get it

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

It somehow tries to rename a file with the same name. How does this happen?

+3
source share
6 answers

This is because bash forshares the element with the space `` '', so you command it to move the ` input` to ' (1)'.

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

Like this:

IFS = $ '\ n'

Then execute your command.

find , -exec.

:

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

. , , .

, .

+3

.

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

#!/bin/bash
shopt -s nullglob
shopt -s extglob
for file in *.txt
do
  newfile="${file//[)]/}"
  newfile="${file// [(]/_}"
  mv "$file" "${newfile%.txt}.in"
done
+3

, $f mv.

, sed \d. [0-9].

+1
for f in *.txt ; do mv "$f" `echo $f | sed -e 's/input\ (\(\d*\))\.txt/input_\1.in/'` ; done
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 video for GNU. Learn more at the same time: http://www.youtube.com/watch?v=OpaiGYxkSuQ

0
source

Source: https://habr.com/ru/post/1760960/


All Articles