LinuxQuestions.org
Support LQ: Use code LQ3 and save $3 on Domain Registration
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 08-14-2014, 04:01 AM   #1
mamunm
LQ Newbie
 
Registered: Apr 2014
Posts: 12

Rep: Reputation: Disabled
bash script to multiply a column


I have a fractional coordinate file which i want to convert to Cartesian coordinate file. In my fractional coordinate file i have lattice vectors, so i stored lattice constant as x_multiplier, y_multiplier and z_multiplier and then i extracted the fractional coordinate part as input.xyz. Now, i have to multiply column 1 with x_multiplier and so on in input.xyz file. i was trying several awk command but nothing is working.As example my x_multiplier is 10 and column 1 is
0.2
0.4
0.6
So, if i use awk '{print $1*10}' input.xyz , everything is fine but i want to use awk '{print $1*$x_multiplier}' input.xyz . It is not working. Can anyone help here? Thanks
 
Old 08-14-2014, 04:18 AM   #2
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Is x_multiplier a shell variable? If this is the case there are some methods to pass shell variables to awk programs. Using the -v option of the awk command is fairly straightforward. For example:
Code:
awk -v x_multiplier=$x_multiplier '{print $1*$x_multiplier}'
I'd like to make you notice that shell variables and variables local to the awk program are two different things, even if they have the same name (as in my example). Moreover, the reason why we embed the awk program in single quotes is precisely to protect the code from the shell expansion.
 
Old 08-14-2014, 06:26 AM   #3
mamunm
LQ Newbie
 
Registered: Apr 2014
Posts: 12

Original Poster
Rep: Reputation: Disabled
It is not working. This is my script:

#!/bin/bash
##bash script to convert POSCAR type file to cartesian
##coordinate file

x_multiplier=$(awk 'NR == 3 {print $1}' CONTCAR);
y_multiplier=$(awk 'NR == 4 {print $2}' CONTCAR);
z_multiplier=$(awk 'NR == 5 {print $3}' CONTCAR);
number_Ru=$(awk 'NR == 7 {print $1}' CONTCAR);
number_C=$(awk 'NR == 7 {print $2}' CONTCAR);
number_O=$(awk 'NR == 7 {print $3}' CONTCAR);
number_H=$(awk 'NR == 7 {print $4}' CONTCAR);
number_atoms=$( echo $number_Ru + $number_C + $number_O + $number_H | bc);
i=10;
j=$(echo 10 + $number_atoms | bc) ;
sed -n -e "$i,$j p" -e "$j q" CONTCAR >CONT.xyz
sed -i 's/T T T//g' CONT.xyz


awk -v x_multiplier=$x_multiplier '{print $1*$x_multiplier}' CONT.xyz






sed -i "1,$number_Ru s/^/Ru/g" CONT.xyz
a=$((number_Ru + 1));
b=$(( number_Ru + number_C ));
sed -i "$a,$b s/^/C/g" CONT.xyz
c=$((b + 1 ));
d=$((b + number_O));
sed -i "$c,$d s/^/O/g" CONT.xyz
e=$((d + 1 ));
f=$((d + number_H));
sed -i "$e,$f s/^/H/g" CONT.xyz

sed -i '1 i\ System' CONT.xyz
sed -i '2 i\$number_atoms' CONT.xyz
sed -i "2 s/.*/$number_atoms/g" CONT.xyz

All the pre-processing and post-processing are finished but i am stucked with the crucial part. I have tried different awk command and nothing is working. Even i found similar type problem in a forum and tried that solution but that is not working in my case.
 
Old 08-14-2014, 07:16 AM   #4
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Well... "it is not working" doesn't help the helpers much!

Looking at your script, I'm pretty sure you might avoid all these awk and sed commands in favor of a single, well built, awk program. I could help - as well as many awk experts here - but we need to see a short but meaningful example of the input (the CONTCAR file or a relevant part of it) and the wanted output (handmade and strictly related to the input you decide to post).

Please, use [CODE][/CODE] tags to embed each of them (in order to improve readability and preserve the original format). If you're new to BB code tags, please take a look here: http://www.linuxquestions.org/questi....php?do=bbcode

Last edited by colucix; 08-14-2014 at 07:17 AM.
 
1 members found this post helpful.
Old 08-14-2014, 08:53 AM   #5
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Looking around (just out of curiosity) I've found a software written in python that might be useful for your tasks, since it can read POSCAR/CONTCAR files. It's called "Atomic Simulation Environment" and the link is https://wiki.fysik.dtu.dk/ase/index.html. Maybe it's worth a look.
 
1 members found this post helpful.
Old 08-14-2014, 09:38 AM   #6
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 5,387

Rep: Reputation: 397Reputation: 397Reputation: 397Reputation: 397
You don't put a "$" for the variable name syntax in awk, I mean it should be
Code:
awk -v x_multiplier=$x_multiplier '{print $1*x_multiplier}' ...
 
2 members found this post helpful.
Old 08-14-2014, 09:53 AM   #7
mamunm
LQ Newbie
 
Registered: Apr 2014
Posts: 12

Original Poster
Rep: Reputation: Disabled
Sorry, I should have been more specific. My input file is
Code:
Surfaces                                
    1.000000000000000     
    32.4575986862182617    0.0000000000000000    0.0000000000000000
     0.0000000000000000   38.4065093994140625    0.0000000000000000
     0.0000000000000000    0.0000000000000000   21.2464694976806641
   Ru   C    O    H 
  24   5   3   9
Selective dynamics
Direct
  0.2994370063145979  0.5876670082410200  0.2210630029439926   T   T   T
  0.3059303363164290  0.5321259895960466  0.2900530099868774   T   T   T
  0.2986823320388794  0.6440023382504805  0.2862089872360229   T   T   T
  0.3404929998020307  0.5322946707407610  0.1799840033054352   T   T   T
.................&&&& more
Output file
Code:
System
41
Ru	9.719006183	22.57023848	4.696808349
Ru	9.929764082	20.43710182	6.162602429
Ru	9.694511268	24.73388186	6.080930517
Ru	11.05158514	20.44358028	3.824024636
........&&&& more
Keefaz's code is working but it is not saving the output, i have to figure that out. Thanks for the help.

Last edited by colucix; 08-14-2014 at 12:19 PM. Reason: Added CODE tags to preserve TABs and indentations.
 
Old 08-14-2014, 10:02 AM   #8
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 5,387

Rep: Reputation: 397Reputation: 397Reputation: 397Reputation: 397
If you have awk > 4.10 version (awk -V), you can use awk -i inplace (changes in place like for sed -i)
Or redirect output to a new file..

Last edited by keefaz; 08-14-2014 at 10:14 AM. Reason: awk inplace option is -i inplace, not just -i
 
1 members found this post helpful.
Old 08-14-2014, 10:11 AM   #9
mamunm
LQ Newbie
 
Registered: Apr 2014
Posts: 12

Original Poster
Rep: Reputation: Disabled
@Colucix : I know about ASE and i want to switch to that platform but at this moment i don't have enough time to learn a new environment but when i will have some free time i will try to learn that.
 
Old 08-14-2014, 10:19 AM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Quote:
Originally Posted by keefaz View Post
You don't put a "$" for the variable name syntax in awk
Good catch. Sorry! A "copy-paste-and-not-cleaning" mistake. I was too focused on the -v option.
 
Old 08-14-2014, 12:17 PM   #11
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
Here is my suggestion (a pure awk script)
Code:
#!/bin/awk -f

NR == 1 {

  print "System"
  
}

NR >= 3 && NR <= 5 {

  multiplier[NR-2] = $(NR-2)
  
}

NR == 6 {

  for ( i = 1; i <= NF; i++ )
    atoms[i] = $i
    
}

NR == 7 {

  for ( i = 1; i <= NF; i++ ) {
    sum ? sum = sum + $i : sum = $i
    array[sum]++
  }
  
  c = 1
  
  print sum

}

NR >= 10 {

  printf "%s", atoms[c]

  #
  #  This is a trick to print floating point numbers with
  #   a fixed number of digits (11 in the desired output).
  #
  for ( i = 1; i <= 3; i++ ) {
    n = $i*multiplier[i]
    p = 11 - int(log(n)/log(10.0)) - 2 
    printf "\t%11." p "f", n
  }
  
  print ""

  if ( NR-9 in array ) c++
  
}
To test (suppose you save the code as "my_script") just do
Code:
$ chmod 744 my_script
$ ./my_script CONTCAR > CONT.xyz
Feel free to ask for any doubt or clarification.

Last edited by colucix; 08-14-2014 at 12:22 PM.
 
1 members found this post helpful.
Old 08-14-2014, 12:21 PM   #12
keefaz
LQ Guru
 
Registered: Mar 2004
Distribution: Slackware
Posts: 5,387

Rep: Reputation: 397Reputation: 397Reputation: 397Reputation: 397
Very nice!
 
Old 08-14-2014, 12:32 PM   #13
mamunm
LQ Newbie
 
Registered: Apr 2014
Posts: 12

Original Poster
Rep: Reputation: Disabled
It's awesome. Thank you very much. I am learning a lot from all of you. I wish i am as good in scripting as all the altruists here.
 
Old 08-14-2014, 12:35 PM   #14
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976Reputation: 1976
@keefaz: Thank you!

@mamunm: You're welcome!

 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with multiply operator in bash gbao256 Programming 6 01-22-2013 12:51 PM
[SOLVED] Script to multiply 29th field in CSV file by 1,56 knilux Programming 44 08-03-2012 12:57 PM
multiply two numbers in Linux script Ghazale Linux - Newbie 5 10-12-2011 10:06 PM
Bash script to suppress matches in two column list xsyntax Linux - General 6 09-03-2010 06:08 AM
Multiply floats in bash script mkrems Linux - Software 5 02-04-2008 08:10 PM


All times are GMT -5. The time now is 05:32 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration