exsonic01
exsonic01

Reputation: 637

Batch copy and rename multiple files in the same directory

I have 20 files like:

01a_AAA_qwe.sh
01b_AAA_asd.sh
01c_AAA_zxc.sh
01d_AAA_rty.sh
...

Files have a similar format in their names. They begin with 01, and they have 01*AAA*.sh format.

I wish to copy and rename files in the same directory, changing the number 01 to 02, 03, 04, and 05:

02a_AAA_qwe.sh
02b_AAA_asd.sh
02c_AAA_zxc.sh
02d_AAA_rty.sh
...

03a_AAA_qwe.sh
03b_AAA_asd.sh
03c_AAA_zxc.sh
03d_AAA_rty.sh
...

04a_AAA_qwe.sh
04b_AAA_asd.sh
04c_AAA_zxc.sh
04d_AAA_rty.sh
...

05a_AAA_qwe.sh
05b_AAA_asd.sh
05c_AAA_zxc.sh
05d_AAA_rty.sh
...

I wish to copy 20 of 01*.sh files to 02*.sh, 03*.sh, and 04*.sh. This will make the total number of files to 100 in the folder.

I'm really not sure how can I achieve this. I was trying to use for loop in the bash script. But not even sure what should I need to select as a for loop index.

for i in {1..4}; do
   cp 0${i}*.sh 0${i+1}*.sh
done

does not work.

Upvotes: 0

Views: 2323

Answers (2)

markp-fuso
markp-fuso

Reputation: 34034

There are going to be a lot of ways to slice-n-dice this one ...

One idea using a for loop, printf + brace expansion, and xargs:

for f in 01*.sh
do
    printf "%s\n" {02..05} | xargs -r -I PFX cp ${f} PFX${f:2}
done

The same thing but saving the printf in a variable up front:

printf -v prefixes "%s\n" {02..05}

for f in 01*.sh
do
    <<< "${prefixes}" xargs -r -I PFX cp ${f} PFX${f:2}
done

Another idea using a pair of for loops:

for f in 01*.sh
do
    for i in {02..05}
    do
        cp "${f}" "${i}${f:2}"
    done
done

Starting with:

$ ls -1 0*.sh
01a_AAA_qwe.sh
01b_AAA_asd.sh
01c_AAA_zxc.sh
01d_AAA_rty.sh

All of the proposed code snippets leave us with:

$ ls -1 0*.sh
01a_AAA_qwe.sh
01b_AAA_asd.sh
01c_AAA_zxc.sh
01d_AAA_rty.sh

02a_AAA_qwe.sh
02b_AAA_asd.sh
02c_AAA_zxc.sh
02d_AAA_rty.sh

03a_AAA_qwe.sh
03b_AAA_asd.sh
03c_AAA_zxc.sh
03d_AAA_rty.sh

04a_AAA_qwe.sh
04b_AAA_asd.sh
04c_AAA_zxc.sh
04d_AAA_rty.sh

05a_AAA_qwe.sh
05b_AAA_asd.sh
05c_AAA_zxc.sh
05d_AAA_rty.sh

NOTE: blank lines added for readability

Upvotes: 1

Barmar
Barmar

Reputation: 780724

You can't do multiple copies in a single cp command, except when copying a bunch of files to a single target directory. cp will not do the name mapping automatically. Wildcards are expanded by the shell, they're not seen by the commands themselves, so it's not possible for them to do pattern matching like this.

To add 1 to a variable, use $((i+1)).

You can use the shell substring expansion operator to get the part of the filename after the first two characters.

for i in {1..4}; do
    for file in 0${i}*.sh; do
        fileend=${file:2}
        cp "$file" "0$((i+1))$fileend"
    done
done

Upvotes: 1

Related Questions