Pages

substrings, brace expansion, sequence expressions

Let's say you have a set of files in a directory named like
exp1eve1.txt
exp1eve2.txt
exp1eve3.txt
exp1eve4.txt
and you want to change the exp1 part to exp2 so they become
exp2eve1.txt
exp2eve2.txt
...


There are so many ways to do the job.
Using substring expansion one could do
#!/bin/bash
for i in exp1eve*.txt; do
mv "$i" "${i:0:3}2${i:4:$((${#i}-3))}"
done

How does the substring expansion work?
(for both bash and ksh)
${parameter:offset:length}
Here is an example
~$ string=inconsiderable
~$ echo ${string:0:1}
i
~$ echo ${string:0:2}
in
~$ echo ${string:2:8}
consider
~$ echo ${string:10:4}
able

brace expansion for bash and zsh
instead of exp1eve*.txt you could also use exp1eve{1,2,3,4}.txt
~$ echo exp1eve{1,2,3,4}.txt
exp1eve1.txt exp1eve2.txt exp1eve3.txt exp1eve4.txt

If you have bash version 3 or later you can also use sequence expressions
(for zsh as well)
~$ echo exp1eve{1..4}.txt
exp1eve1.txt exp1eve2.txt exp1eve3.txt exp1eve4.txt
~$ echo exp{1,2}eve{1..4}.txt
exp1eve1.txt exp1eve2.txt exp1eve3.txt exp1eve4.txt 
exp2eve1.txt exp2eve2.txt exp2eve3.txt exp2eve4.txt

You can use sequence expressions in loops
~$ for i in {1..4};do echo $i; done
1
2
3
4

Here is another way of changing exp1 filenames to exp2 using sequence expression
#!/bin/bash
b=(exp{10,2}eve{1..11}.txt)
for ((i=0;i<$((${#b[@]}/2));i++)); do
mv "${b[$i]}" "${b[$((i+${#b[@]}/2))]}"
done
using sort we could also do
#!/bin/bash
b=($(printf "%s\n" exp{1,2}eve{1..4}.txt|sort -k1.8n))
printf "mv %s %s\n" ${b[@]}|sh

Be creative, the possibilities are endless.

No comments: