2

I have a list of files like

Ortho234.phy
Ortho671.phy
Ortho880.phy and so on

I would like to rename them for an array job to

Ortho234.1.phy
Ortho671.2.phy
Ortho880.3.phy

I tried this but this replaces and just names the file as 1.phy, 2.phy and so on.

 a=1
 for i in *.phy; do
     new=$(printf "%04d.phy" "$a") 
     mv -- "$i" "$new"
     let a=a+1
 done
Paul
  • 1,077
  • 3
  • 14
  • 27
  • 1
    `i` is your filename and you aren't using it. – Arijoon Feb 17 '17 at 21:02
  • Personally I feel you have an x<->y problem as you have gained no benefit by renaming the files and would better off asking for help with your actual array problem. Files are still in the same order as they were prior to adding the new numbers. – grail Feb 18 '17 at 10:44

4 Answers4

5

Any one of the following commands will do your job

c=0 rename 's/\./sprintf(".%d.",++$ENV{c})/e' *.phy  

rename 's/\./".".++$a."."/e' *.phy                  

rename '$a++; s/\./.$a./e' *.phy                   

n=1;for f in *.phy; do mv "$f" "${f%.*}.$n.${f##*.}"; n=$((n+1)); done

Either

It executes the perl s/// expression, and performs the rename from the original to the replaced string. In the replacement string I use sprintf to format the name, where I use the environment variable cas the counter

$ touch Ortho234.phy  Ortho671.phy  Ortho880.phy

$ ls *.phy -1
Ortho234.phy
Ortho671.phy
Ortho880.phy

$ c=0 rename 's/\./sprintf(".%d.",++$ENV{c})/e' *.phy

$ ls *.phy -1
Ortho234.1.phy
Ortho671.2.phy
Ortho880.3.phy

OR

$ touch Ortho234.phy  Ortho671.phy  Ortho880.phy

$ ls *.phy -1
Ortho234.phy  
Ortho671.phy  
Ortho880.phy

$ n=1;for f in *.phy; do mv "$f" "${f%.*}.$n.${f##*.}"; n=$((n+1)); done

$ ls *.phy -1
Ortho234.1.phy  
Ortho671.2.phy  
Ortho880.3.phy

OR

$ touch Ortho234.phy  Ortho671.phy  Ortho880.phy

$ ls *.phy -1
Ortho234.phy
Ortho671.phy
Ortho880.phy

$ rename 's/\./".".++$a."."/e' *.phy

$ ls *.phy -1
Ortho234.1.phy
Ortho671.2.phy
Ortho880.3.phy

OR

$ touch Ortho234.phy  Ortho671.phy  Ortho880.phy

$ ls *.phy -1
Ortho234.phy
Ortho671.phy
Ortho880.phy

$ rename '$a++; s/\./.$a./e' *.phy

$ ls *.phy -1
Ortho234.1.phy
Ortho671.2.phy
Ortho880.3.phy
Akshay Hegde
  • 16,536
  • 2
  • 22
  • 36
  • I pick door number 2! (Portability++) ... And I'll upvote if you remove the [ParsingLS](http://mywiki.wooledge.org/ParsingLs) option. :-) – ghoti Feb 17 '17 at 22:23
  • can also use `rename 's/\./".".++$a."."/e' *.phy` or `rename '$a++; s/\./".$a."/e' *.phy`, takes advantage of [sort global variables](https://stackoverflow.com/questions/26127617/what-exactly-are-a-and-b-in-perls-sort-function) – Sundeep Feb 18 '17 at 01:53
  • 1
    @Sundeep: Thanks for the suggestion – Akshay Hegde Feb 18 '17 at 03:59
  • just realized that `e` is not needed for 2nd suggestion, `rename '$a++; s/\./.$a./' *.phy` – Sundeep Feb 18 '17 at 04:18
  • what does e stand for the expression 's/\./".".++$a."."/e' ? If I am not getting it wrong "." before and after ++$a is a string concatenate operator of perl ? – Vicky Feb 20 '17 at 07:16
  • @Vicky : `e` modifier enables evaluation in the substitution – Akshay Hegde Feb 20 '17 at 07:41
  • @AkshayHegde: thanks but do you have a link or a document where I can read about that more ? also if you could confirm on my second part "If I am not getting it wrong "." before and after ++$a is a string concatenate operator of perl ? " in my post earlier , thanks in advance – Vicky Feb 20 '17 at 09:19
  • @Vicky: Here we are searching for `.` and replacing with `..` , in first example `rename 's/\./".".++$a."."/e' *.phy` yes its `".".`<- this dot is for string concatenation, that is `"." "."`. `"."` is just string but next dot without quote is concatenation operator, I hope its clear now – Akshay Hegde Feb 20 '17 at 10:15
  • @Vicky : please follow this link http://www.perlmonks.org/?node_id=1007141 – Akshay Hegde Feb 20 '17 at 13:07
  • Thanks Akshay but unfortunately this rename syntax seems to be not supported on my bash version. I am using 4.1.11. Do you know which bash version supports it ? – Vicky Feb 20 '17 at 16:06
  • @Vicky: This is my rename version `rename --version` gives `/usr/bin/rename using File::Rename version 0.20` – Akshay Hegde Feb 20 '17 at 16:09
  • @AkshayHegde: rename --version gives me rename from util-linux 2.21.2 – Vicky Feb 20 '17 at 19:55
  • @Akshay: there is no error the command just runs quietly and when I check the output I don't the the files renamed – Vicky Feb 21 '17 at 06:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136272/discussion-between-akshay-hegde-and-vicky). – Akshay Hegde Feb 21 '17 at 18:30
1

This should do the job:

a=1
for i in *.phy; do
filepart=$(echo $i | sed 's/.phy//g')
new=$(printf "%s.%d.phy" "$filepart" "$a")
mv -- "$i" "$new"
let a=a+1
done

filepart is filename, without the extension.

Nuclear
  • 1,316
  • 1
  • 11
  • 17
1
awk -F\. '{print $1"."NR"."$2}' file

Ortho234.1.phy
Ortho671.2.phy
Ortho880.3.phy
Claes Wikner
  • 1,457
  • 1
  • 9
  • 8
1

awk command is also help in getting the desired output. NR gives the line number and split the input on . and rewrite the array as per the needed like following

awk '{split($0,a,"."); print a[1]"."NR"."a[2]}' file

file is the input file containing the following values

Ortho234.phy
Ortho671.phy
Ortho880.phy
R. Kumar
  • 103
  • 5
  • awk could read Input_file itself no need to use cat Input_file | awk .... command then. It is usually called UUOC(Useless use of cat command). – RavinderSingh13 Feb 19 '17 at 18:17