I've been writing bash script on and off, with pretty good results in terms of getting the job done. However, I'm worried that my script might be very ugly, as I am a beginner. I'm looking for advice concerning this particular one.
I want to extract some part of a big text file (here a lammps .lmps file), and manipulate it to create another file (here .xyz).
The interesting parts of the big file are:
The beginning of the file:
300 atoms 300 bonds 450 angles 600 dihedrals 150 impropers
The part about atom tag (here either "1" or "2") and mass:
Masses 1 12.011150 2 1.007970 Pair Coeffs
The part concerning atom coordinates:
Atoms 1 1 1 -0.126800 20.511864 28.359121 11.290877 2 1 1 -0.126800 21.779636 28.644716 10.779171 3 1 1 -0.126800 20.381316 27.822484 12.573717 4 1 1 -0.126800 21.518471 27.571445 13.344853 5 1 1 -0.126800 22.786244 27.857074 12.833161 6 1 1 -0.126800 22.916794 28.393694 11.550321 7 1 2 0.126800 19.390282 27.599170 12.973874 8 1 2 0.126800 19.622826 28.555315 10.688110 9 1 2 0.126800 23.907808 28.617021 11.150121 10 1 2 0.126800 21.881943 29.064261 9.776262 11 1 2 0.126800 23.675251 27.660865 13.435963 12 1 2 0.126800 21.416213 27.151893 14.347761 Bonds
Now here's the script I wrote, with some comments to explain what I wanted to do:
#!/bin/bash/
echo "LAMMPS file name? (without .lmps)"
read -r filename
# Make sure file exists
if [ -r "$filename".lmps ]; then
# Appends number of atoms to xyz file
head "$filename".lmps | grep atoms | awk -F' ' '{print $1}' > "$filename".xyz
echo >> "$filename".xyz
# Extracts "atom coordinates" and "masses" sections from original lmps file
awk '/Atoms/,/Bonds/' "$filename".lmps | head -n -2 | tail -n +3 > coordinates.tmp
awk '/Masses/,/Pair Coeffs/' "$filename".lmps | head -n -2 | tail -n +3 > masses.tmp
# Iterates over all lines of atom coordinates
while read line_atoms
do
# Iterates over all lines of masses
while read line_masses
do
mass=`echo $line_masses | awk -F' ' '{print $2}'`
tag=`echo $line_masses | awk -F' ' '{print $1}'`
case $mass in
# If mass corresponds to carbon and current line has lammps "carbon" tag
# then append this line to the xyz file
12.011150)
if [ "$tag" == `echo $line_atoms | awk -F' ' '{print $3}'` ]; then
echo -e "C\t`echo $line_atoms | awk -F' ' '{print $5,"\t",$6,"\t",$7}'`" >> "$filename".xyz
fi
;;
# Same, checks for Hydrogen mass and lammps "hydrogen" tag
1.007970)
if [ "$tag" == `echo $line_atoms | awk -F' ' '{print $3}'` ]; then
echo -e "H\t`echo $line_atoms | awk -F' ' '{print $5,"\t",$6,"\t",$7}'`" >> "$filename".xyz
fi
;;
esac
done < masses.tmp
done < coordinates.tmp
# In case the requested file doesn't exist
else echo "Error:"$filename".lmps doesn't exits"
fi
# Gets rid of temporary files
rm *.tmp
The script works properly, and yields something like:
300 C 20.511864 28.359121 11.290877 C 21.779636 28.644716 10.779171 C 20.381316 27.822484 12.573717 C 21.518471 27.571445 13.344853 C 22.786244 27.857074 12.833161 C 22.916794 28.393694 11.550321 H 19.390282 27.599170 12.973874 H 19.622826 28.555315 10.688110 H 23.907808 28.617021 11.150121 H 21.881943 29.064261 9.776262 H 23.675251 27.660865 13.435963 H 21.416213 27.151893 14.347761
I feel like it is very inefficient (the double while read line
, the commands inside if [ ]
conditions, and so on) so I'd very much like some input in order to improve my coding skills. Feel free to tell me if it looks good or awful to you, and why!