2016-05-17 10 views
0

Ich möchte, ob unter Shell-Skript wissen, kann weiterVereinfachen der Bash-Shell-Skript-Schleife

#!/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

[Bearbeiten] Ihre Frage etwas prägnant, prüfbare Abtastwerteingang (Inhalt von 'CONTCAR') aufzunehmen und erwartete Ausgabe und jemand wird Ihnen zeigen, wie es zu tun * * viel ** einfacher und ohne Schleife. Lesen Sie auch [why-is-using-a-shell-loop-to-process-text-betrachtet-schlechte-praxis] (http://unix.stackexchange.com/questions/169716/why-is-using-a- shell-loop-to-process-text-betrachtet-schlechte-praxis) –

+1

Wow, Stéphane Chazelas Antwort in der oben genannten Frage von @ EdMorton ist ein erstaunliches Muss gelesen, perfekt für diese Frage. –

+2

'Katze CONTCAR | Kopf -5 | Schwanz -3 | Kopf -1 | awk '{print $ 1}' 'ist genau äquivalent zu' awk 'NR == 3 {print $ 1}' CONTCAR' –

Antwort

2

durch die Verwendung einer Schleife vereinfacht werden, wenn Sie möchten, können Sie nicht Arrays Schleife verwenden, ist nicht da Variablen In den verschiedenen Namen zugewiesen, können Sie es etwas vereinfachen, obwohl

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

je nachdem, was Sie alle diese neun Variablen kann es besser sein, Lösungen verwenden werden.

+0

Danke !! Es klappt! Was ist, wenn die Variablennamen gleich sind und nur der Index verschieden ist als a11 a12 a13 a21 a22 a23 a31 a32 a33, dann ist eine weitere Vereinfachung möglich? – user4914499

+0

sie sind alle unterschiedliche Namen, verschiedene Variablen. Was ich meinte, war Bash-Arrays, aber wieder hängt davon ab, was Sie mit denen tun werden. – karakfa

+0

OK. Ruhe Frage: Ich bin nicht klar, die Verwendung von "<<". Kannst du das erklären? Vielen Dank im Voraus – user4914499

0

Unter der Annahme, dass Ihre Absicht, nur Gebrauch ist Werte 1,2 & 3 aus jedem Bereich, in dem die letzte Ziffer des Wertes, was in der awk Teil und der ersten Ziffer des Wertes, die für die head Teil erforderlich ist - Sie können so etwas wie dies versuchen:

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 ; 
3

Da Sie keine Abtastwerteingang und erwartete Ausgabe zur Verfügung gestellt haben, das ist nur eine Vermutung, aber es kann sein, was Sie wollen:

$ 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 

aber yo Sie sollten Arrays anstelle aller einzelnen Variablen verwenden.

2

Noch ein anderer Weg, es zu tun:

{ 
    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