简体   繁体   English

使用循环简化Bash Shell脚本

[英]Simplifying Bash shell script using loop

I'd like to know whether below shell script can be simplified further by using a loop 我想知道是否可以通过使用循环来进一步简化下面的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}'`

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. 但是您应该考虑使用数组而不是所有单个变量。

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. 根据您将要使用所有这九个变量的不同,可能会有更好的解决方案。

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

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: 假设您的意图是仅使用值的最后一位是awk部分中所要求的值和head部分所需的值中的第一位的任何范围的值1,2和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 ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM