使用循环简化Bash shell脚本

时间:2016-05-17 00:18:17

标签: bash awk

我想知道使用循环

是否可以进一步简化下面的shell脚本
#!/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}'`

4 个答案:

答案 0 :(得分:3)

由于您还没有提供任何样本输入和预期输出,这只是猜测,但它可能是您想要的:

$ 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

但您应该考虑使用数组而不是所有单个变量。

答案 1 :(得分:2)

如果您不想使用数组循环是不可能的,因为变量被分配给不同的名称,您可以稍微简化一下

$ 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) 

取决于您将要使用的所有这九个变量,可能有更好的解决方案。

答案 2 :(得分:2)

另一种方法:

{
    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

答案 3 :(得分:0)

假设您的意图是仅使用值1,2&amp; 3,awk部分所需值的最后一位数和head部分所需值的第一位数 - 的任何范围内的3 - 您可以尝试这样的事情:

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 ;