Rename folder

hi guys

i have a group of directory like these

p1( 15 - 16 )
p2( 17 -15 ) 
p1 ( 14 - 20 )
p2 ( 13 -17 )
..
.
.

directories contain numbers represent time
i want to rename all directories and change all numbers in directories' name .
for example

p1( 15 -16 ) will change to p1(14.40 - 15.50 )
p2( 17 -15 ) to p2( 16.50 - 14.50 )
p1 ( 14 -20 ) to p1( 13.50 - 19.50 )

and .....

what is the best way to do that???

That spec is a bit vague. Where do you get the times from? Is it always 10 min to the full hour? Try the mv command.

named are fixed

for example
i have 100 directories like those

p1( 18 - 20 ) 
p3( 17 - 18 )
p1( 21 -23 )

and i want to rename those folder like that

p1( 18 - 20 ) to p1 ( 17.50 - 19.50 )
p3( 17 - 18 ) to p3( 16.50  - 17.50 )
p1( 21 -23 ) to p1( 20.50  -22.50 )

the only thing must be change is number is directories name !

how can i do that !! mv is not useful

Why is mv not useful?

mkdir "p1( 15 -16 )"
mv "p1( 15 -16 )" "p1(14.50 - 15.50)"
ls -d p*
p1(14.50 - 15.50)/

works!

!!!!!!!!!!!!!!!!!!!!! useful ??? :))

first of all , directories created before and now i want to rename all of them !!
u just use simple mv to rename one directory !! how about 1000 directories with different number ????

why we use shell script . your work is like that to rename all directories manually !!!!!

i want to write shell script to grep for example 17 in all file names and change all of them to 16.50 and like that !!!

@mhs: Please do not leave people guessing. Show a representative sample of input, desired output, attempts at a solution and specify what OS and versions being used.

input directories

p8( 18.30 - 19 )
p1( 12 - 14 )
p4( 18  - 21 )
p1( 16 - 18 )
p2( 14  - 18 )
p1( 20 - 22 )
p1( 10 - 12 )
p3( 17  - 19 )
p2( 7.30 - 8 )
p4 ( 6.30 - 7.30 )
.
.
.
.

output directories

p8( 18.20 - 18.50 )
p1( 11.50 - 13.50 )
p4( 17.50  - 20.50 )
p1( 15.50 - 17.50 )
p2( 13.50  - 17.50 )
p1( 19.50 - 21.50 )
p1( 9.50 - 11.50 )
p3( 16.50  - 18.50 )
p2( 7.20 - 7.50 )
p4 ( 6.20 - 7.20 )
.
.
.
.

i wrote a simple code but i dont know how to expand that for this work

for example to change all 18 to 17.50

find . -type d  | while  read FILE
do
echo "$FILE" | grep 18 | sed 's/18/17.50/g'
done

and so on but my code does not make sense because 18 should be a counter from 1 to 23 and every time change in grep and sed to rename all directories .

any idea ????

hi,
If your OS is Linux, you can try:

#!/bin/bash
find . -type d -name "p*" | while  read i
do
        read d1 d2 < <(echo "$i" | sed 's/ //g;s/.*(\([0-9.]\+\)-\([0-9.]\+\))/\1 \2/;s/\./:/g')
        m1=$(date --date="$d1 10 minutes ago" "+%H.%M")
        m2=$(date --date="$d2 10 minutes ago" "+%H.%M")
        d1=${d1/:/.}
        d2=${d2/:/.}
        j=$(echo "$i" | sed 's/\(.*( *\)'$d1'\( *- *\)'$d2'\( *)\)/\1'$m1'\2'$m2'\3/')
        echo mv "$i" "$j"
done

PS: This script no execute mv but print the command.

Regards.

1 Like

If you don't have GNU date available, this might work

#!/bin/bash
find . -type d -name "p*" | 
awk    '    {printf "%s \"%s\" ", "mv", $0
             $2 = sprintf ("%4.2f", $2-(($2==int($2))?0.5:0.1))
             $4 = sprintf ("%4.2f", $4-(($4==int($4))?0.5:0.1))
             printf "\"%s\"\n", $0
            }
       ' > tmpscript.sh
. ./tmpscript.sh
rm tmpscript.sh
1 Like
 > tmpscript.sh
. ./tmpscript.sh
rm tmpscript.sh

is about the same as

 | sh

Verbose dry-run:

 | sh -nv
2 Likes

Absolutely. Didn't think of that!

1 Like

@Rudic: Maybe, it's not important, but not work with (example) p1( 00 - 02.05 )

Regards.

1 Like

awesome and brilliant . thx alot man .
could you explain a bit about i sed in your script i know what they do bu t i want to know about g;s \2/ and '\3/' .g;s/.*(\([0-9.]\+\)

sed 's/ //g;s/.*(\([0-9.]\+\)-\([0-9.]\+\))/\1 \2/;s/\./:/g'

and

sed 's/\(.*( *\)'$d1'\( *- *\)'$d2'\( *)\)/\1'$m1'\2'$m2'\3/'

---------- Post updated 09-16-13 at 01:49 AM ---------- Previous update was 09-15-13 at 10:34 PM ----------

i have a another problem with this kind of directories

P3 ( 9 - 10 ) = 111
P2 ( 13 - 11 ) = 112
P3 ( 4 - 8 ) = 114

script does not work for this kind of folder .

Ok,
In first time, the script should work fine if you replace:

sed 's/ //g;s/.*(\([0-9.]\+\)-\([0-9.]\+\))/\1 \2/;s/\./:/g'

by

sed 's/ //g;s/.*(\([0-9.]\+\)-\([0-9.]\+\)).*/\1 \2/;s/\./:/g'

Explanation:
g ==> global, so with command s, the replace is global instead of only first occurence.
\(....\) => catch arguments and \1 reference argument 1,\2 argument 2,...
[0-9] => number 0 to 9
\+ => 1 or more the left character class so [0-9]\+ ==> 1 number or more number.

Regards.

1 Like

thx a lot man

---------- Post updated at 06:36 AM ---------- Previous update was at 06:27 AM ----------
for these kind of directories like

P3 ( 9 - 10 ) = 111

P2 ( 13 - 11 ) = 112

P3 ( 4 - 8 ) = 114

for some reasons i've changed a bit that script

i used awk to detect d1 and d2

d1=$(echo  "$i" |awk '{print  $3}'|sed 's/\.//')
d2=$(echo  "$i" |awk '{print  $5}' | sed 's/\.//')

instead of

read d1 d2 < <(echo "$i" | sed 's/ //g;s/.*(\([0-9.]\+\)-\([0-9.]\+\))/\1 \2/;s/\./:/g')

and then

m1=$(date --date="${d1} 10 minutes " "+%H.%M")
 m2=$(date --date="${d2} 10 minutes " "+%H.%M")

and then i used awk to substitute new values with old values

j=$(echo "$i1" |awk '{gsub($3,"$m1",$3) && gsub($5,"$m2",$5); print }') 

instead of

j=$(echo "$i" | sed 's/\(.*( *\)'$d1'\( *- *\)'$d2'\( *)\)/\1'$m1'\2'$m2'\3/')

but my problem is with awk after substitution output is like
P3 ( $m1 - $m2 ) = 114

instead of replacing m1 and m2 with their values .

how can i use awk or sed to substitution m1 and m2 with old values for these kind of directories

P3 ( 4 - 8 ) = 114

P3 ( 8.30 - 11.30 ) = 113

Just replace:

j=$(echo "$i1" |awk '{gsub($3,"$m1",$3) && gsub($5,"$m2",$5); print }')

by

j=$(echo "$i1" |awk '{gsub($3,"'$m1'",$3) && gsub($5,"'$m2'",$5); print }')

should work.

I edit this post to correct: double quote must in simple quote.

Regards.

thx a million man . you are awesome !!