1

I have written a bash script which searches all my directories and extracts some data that I need from files. Every thing works fine until I want to subtract the fist column of my files with a constant which is changing in each directory. The code looks like:

#!/bin/bash
ROOT=$(pwd)
#DIRS=$(find -name "*99")
DIRS[1]=99
DIRS[2]=199
DIRS[3]=299
DIRS[4]=399
DIRS[5]=499
DIRS[6]=599
DIRS[7]=699
DIRS[8]=799
DIRS[9]=899
DIRS[10]=999

for DIR in 1 2 3 4 5 6 7 8 9 10
  do
    dir=${DIRS[${DIR}]}
    cd $dir

CDIR=$(pwd)
if [ $CDIR = $ROOT ]; then
    continue
fi

#echo $CDIR

EFERMI=$(grep "E-fermi" OUTCAR | tail -n 1 | awk '{print $3}')
echo $EFERMI

# DOS
head -n 3007 DOSCAR | tail -n 3001 > DOS

cat DOS | awk '{print $1-$EFERMI , ($2+$3)/32}' > shifted_DOS_$dir
cat DOS | awk '{print $1 , ($2+$3)/32}' > nshifted_DOS_$dir
cp shifted_DOS_$dir  $ROOT"/PLOTS"
cp nshifted_DOS_$dir $ROOT"/PLOTS"
cd $ROOT
done

The line "awk '{print $1-$EFERMI ..." is not working properly and it gives back wrong numbers for the first column. It is a constant shift which is different in each iteration, so it should follow the same logic as is mensioned in: how to subtract a constant number from a column but apparently it cannot distinguish $EFERMI value. Any idea how to do this without going to each directory and manually do the awk command separately?!

Thanks in advance

Community
  • 1
  • 1
elhmo
  • 35
  • 3
  • Rather than changing directory and changing back, you can run the loop inside a subshell. This also allows parallelization: `for dir in ${DIRS[@]}; do ( ... ) & done`. (The parentheses and `&` are literal, the `...` indicates code that runs in a subshell). And don't pipe `cat` to `awk`. `awk` knows how to read files. – William Pursell Nov 06 '13 at 13:53

1 Answers1

2

Instead of:

awk '{print $1-$EFERMI , ($2+$3)/32}' 

Use:

awk -v EFERMI=$EFERMI '{print ($1-EFERMI), ($2+$3)/32}'

That is the proper way of passing shell variable to awk.

In your awk command $EFERMI is inside single quotes hence shell doesn't expand it's value.

anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 2
    In fact it's worse than "shell doesn't expand" -- awk expands it thusly: the awk variable "EFFERMI" is null, so awk will substitute an empty string or zero depending on the context; EFFERMI is preceded by a "$", so awk thinks you want the value of a column and substitutes the empty variable with 0, so effectively you get `$1-$0`. In a arithmetic context, awk will only consider the leading digits of a string (i.e. (5 - "123 abc") is treated as (5 - 123)), so `$1 - $0` will probably become `$1 - $1` or zero. – glenn jackman Nov 06 '13 at 14:39