awk print variable

I have list of files:

ls
a.pdf
b.pdf
c.pdf

and so on...

and I have a file like this:

cat file1
apple
mango
pear

and so on...

I want to rename my file like this:

mv a.pdf a-apple.pdf
mv b.pdf b-mango.pdf
mv c.pdf c-pear.pdf

and so on...

So far I have in mind something like this:

for i in `ls`
do
mv $i $(echo $i|awk -F. '{print $1'$(awk {NR==$j} file1)'"."$2})'
done

but I know that has many problems which I need some help to solve.
Please help. Thanks.

Try this

#!/bin/ksh

j=1
for i in *.pdf; do
prefix=$( echo $i | cut -f1 -d"." ); suffix=$( echo $i | cut -f2 -d"." )
newfile=$prefix"-"$( awk -F. -v j=$j 'NR==j {print $1}' file1 )"."$suffix
mv $i $newfile; ((j=j+1))
done

regards,
Ahamed

Another one:

awk 'BEGIN {
  while ((getline < "file1") > 0) { 
    split(ARGV[ ++c ], x, ".")
    printf "mv -- \"%s\" \"%s-%s.%s\"\n", \
      ARGV[c], x[1], $1, x[2]
  }
}' *.pdf

An example:

zsh-4.3.11[t]% cat file1
apple
mango
pear
zsh-4.3.11[t]% ls *pdf
a.pdf  b.pdf  c.pdf
zsh-4.3.11[t]% awk 'BEGIN {
quote>   while ((getline < "file1") > 0) { 
quote>     split(ARGV[ ++c ], x, ".")
quote> printf "mv -- \"%s\" \"%s-%s.%s\"\n", \
quote>   ARGV[c], x[1], $1, x[2]
quote>   }
quote> }' *.pdf | bash -xv
mv -- "a.pdf" "a-apple.pdf"
+ mv -- a.pdf a-apple.pdf
mv -- "b.pdf" "b-mango.pdf"
+ mv -- b.pdf b-mango.pdf
mv -- "c.pdf" "c-pear.pdf"
+ mv -- c.pdf c-pear.pdf
zsh-4.3.11[t]% ls *pdf
a-apple.pdf  b-mango.pdf  c-pear.pdf
2 Likes

Thank you to both of you. I am going to test it it just that I just realized that my pdf files order is all wrong. The files order is like this when I run ls:

filex-1.pdf
filex-11.pdf
filex-2.pdf
filex-23.pdf
filex-216.pdf
filex-3.pdf
filex-35.pdf

and so on.....

How can I sort it so it will be like this:

filex-1.pdf
filex-2.pdf
filex-3.pdf
filex-11.pdf
filex-23.pdf
filex-35.pdf
filex-216.pdf

I think may be I can add "0" before the number part of the file names, so if the total of digit is only 1 add 2 more "0"s in front of it and add 1 more "0" if the total of digit is 2. Any better ideas on how shell script may help?

It's easy to fix,
how exactly the new file names should look like?

The code below will rename filex-1.pdf to filex-1-apple.pdf :

printf '%s\n' *.pdf |
  sort -t- -k2n |
    awk -F. 'getline f1 < "file1" {
      printf "mv -- \"%s\" \"%s-%s\.%s\"\n", \
        $0, $1, f1, $2
      }' | bash -xv
1 Like

Your first codes seem to be very advance to a newbie like me. but thank you radoulov. it works. Can you explain your codes:

awk 'BEGIN {
  while ((getline < "file1") > 0) { 
    split(ARGV[ ++c ], x, ".")
    printf "mv -- \"%s\" \"%s-%s.%s\"\n", \
      ARGV[c], x[1], $1, x[2]
  }
}' *.pdf

ARGV will have the values *.pdf i.e. a.pdf, b.pdf and c.pdf
so ARGV[1] is a.pdf, ARGV[2] is b.pdf and so on
this is what the code does

  1. reads from the file "file1" # while ((getline < file1) > 0)
  2. splits the ARGV into prefix and suffix and stores it in the array x. # split(ARGV[ ++c ], x, "."). c is incremented for the next value for next cycle. x will have x[1] => a and x[2] => pdf. As you can see, "." is used for splitting. Google awk split for more info.
  3. Prints the mv command with old and new file name. Old file name is present in ARGV and new file name is formed from $1=>apple - which is read from the file, x[1]=>a, x[2]=>pdf
  4. bash -v will execute the command whatever is given to it

regards,
Ahamed

1 Like