user4914499
user4914499

Reputation: 354

Simplifying Bash shell script using loop

I'd like to know whether below shell script can be simplified further by using a loop

#!/bin/bash

a11=`cat CONTCAR | head -5 | tail -3 | head -1 | awk '{print $1}'`
a12=`cat CONTCAR | head -5 | tail -3 | head -1 | awk '{print $2}'`
a13=`cat CONTCAR | head -5 | tail -3 | head -1 | awk '{print $3}'`
b21=`cat CONTCAR | head -5 | tail -3 | head -2 | awk '{print $1}'`
b22=`cat CONTCAR | head -5 | tail -3 | head -2 | awk '{print $2}'`
b23=`cat CONTCAR | head -5 | tail -3 | head -2 | awk '{print $3}'`
c31=`cat CONTCAR | head -5 | tail -3 | head -3 | awk '{print $1}'`
c32=`cat CONTCAR | head -5 | tail -3 | head -3 | awk '{print $2}'`
c33=`cat CONTCAR | head -5 | tail -3 | head -3 | awk '{print $3}'`

Upvotes: 0

Views: 92

Answers (4)

Gordon Davisson
Gordon Davisson

Reputation: 125708

Yet another way to do it:

{
    read ignored # ignore first two lines
    read ignored
    read a11 a12 a13 ignored # "ignored" is needed to keep fields 4 on from being included in a13
    read b11 b12 b13 ignored
    read c11 c12 c13 ignored
} <CONTCAR

Upvotes: 2

Ed Morton
Ed Morton

Reputation: 203189

Since you haven't provided any sample input and expected output, this is just a guess but it MAY be what you want:

$ cat file
x1 x2 x3 x4
y1 y2 y3 y4
a1 a2 a3 a4
b1 b2 b3 b4
c1 c2 c3 c4
d1 d2 d3 d4
$
$ cat tst.awk
NR>2 && NR<6 {
    for (i=1; i<=3; i++) {
        printf "%c%d%d=%s\n", 97+(NR-3), NR-2, i, $i
    }
}
$
$ declare $(awk -f tst.awk file)
$
$ echo "$a11"
a1
$ echo "$b22"
b2
$ echo "$c33"
c3

but you should consider using arrays instead of all individual variables.

Upvotes: 3

aphorise
aphorise

Reputation: 354

Assuming that your intent is to only use values 1,2 & 3 from any range where the last digit of the value is whats required in the awk part and the first digit of the value required for the head part - you can try something like this:

for iX in `seq -f %02g 11 33`; do
        if ((${iX:1:1} != 1)) && ((${iX:1:1} != 2)) && ((${iX:1:1} != 3)) ; then
                echo "skipping ${iX}" ; continue ;
        else  # echo "PROCESSING: ${iX}" ;
                TOEXEC="$(cat CONTCAR | head -5 | tail -3 | head -${iX:0:1} | awk '{print ${iX:1:1}}')"
        fi ;
done ;

Upvotes: 0

karakfa
karakfa

Reputation: 67467

If you don't want to use arrays loop is not possible since variables are assigned to different names, you can simplify it little bit though

$ read a11 a12 a13 < <(awk 'NR==3{print $1,$2,$3}' CONTCAR)     
$ read b21 b22 b23 < <(awk 'NR==4{print $1,$2,$3}' CONTCAR)        
$ read c31 c32 c33 < <(awk 'NR==5{print $1,$2,$3}' CONTCAR) 

depending on what you are going to use all these nine variables there may be better solutions.

Upvotes: 2

Related Questions