Können wir Shell-Variablen in awk verwenden?

Können wir Shell-Variablen in AWK wie $VAR anstelle von $1 , $2 ? Beispielsweise:

 UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW) NUSR=`echo ${UL[*]}|awk -F, '{print NF}'` echo $NUSR echo ${UL[*]}|awk -F, '{print $NUSR}' 

Eigentlich bin ich ein oracle DBA, wir bekommen viele Importanfragen. Ich versuche es mit dem Skript zu automatisieren. Das Skript ermittelt die Benutzer im Speicherauszug und fragt nach den Benutzern, für die der Speicherauszug geladen werden muss.

Angenommen, die Dumps haben zwei Benutzer AKHIL , SWATHI (es kann SWATHI Benutzer im Dump geben und ich möchte mehr Benutzer importieren). Ich möchte die Dumps zu neuen Benutzern AKHIL_NEW und SWATHI_NEW . So die Eingabe zu lesen einige denken wie AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW .

Zuerst muss ich die Anzahl der Benutzer finden, die erstellt werden sollen, dann muss ich neue Benutzer, dh AKHIL_NEW,SWATHI_NEW von der Eingabe, die wir angegeben haben, bekommen. Damit kann ich mich mit der database verbinden und die neuen Benutzer anlegen und dann importieren. Ich kopiere nicht den gesamten Code: Ich habe den Code einfach kopiert, von wo er die eingegebenen Benutzer akzeptiert.

 UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW) ## it can be many users like USER1:USER1_NEW,USER2_USER2_NEW,USER3:USER_NEW.. NUSR=`echo ${UL[*]}|awk -F, '{print NF}'` #finding number of fields or users y=1 while [ $y -le $NUSR ] ; do USER=`echo ${UL[*]}|awk -F, -v NUSR=$y '{print $NUSR}' |awk -F: '{print $2}'` #getting Users to created AKHIL_NEW and SWATHI_NEW and passing to SQLPLUS if [[ $USER = SCPO* ]]; then TBS=SCPODATA else if [[ $USER = WWF* ]]; then TBS=WWFDATA else if [[ $USER = STSC* ]]; then TBS=SCPODATA else if [[ $USER = CSM* ]]; then TBS=CSMDATA else if [[ $USER = TMM* ]]; then TBS=TMDATA else if [[ $USER = IGP* ]]; then TBS=IGPDATA fi fi fi fi fi fi sqlplus -s '/ as sysdba' <<EOF # CREATING the USERS in the database CREATE USER $USER IDENTIFIED BY $USER DEFAULT TABLESPACE $TBS TEMPORARY TABLESPACE TEMP QUOTA 0K on SYSTEM QUOTA UNLIMITED ON $TBS; GRANT CONNECT, CREATE TABLE, CREATE VIEW, CREATE SYNONYM, CREATE SEQUENCE, CREATE DATABASE LINK, RESOURCE, SELECT_CATALOG_ROLE to $USER; EOF y=`expr $y + 1` done impdp sysem/manager DIRECTORY=DATA_PUMP DUMPFILE=imp.dp logfile=impdp.log SCHEMAS=AKHIL,SWATHI REMPA_SCHEMA=${UL[*]} 

Im letzten impdp-Befehl muss ich die ursprünglichen Benutzer in die Dumps holen, dh AKHIL, SWATHI mit den Variablen.

Ja, Sie können die Shell-Variablen in awk verwenden. Es gibt eine Reihe von Möglichkeiten, dies zu tun, aber am liebsten definiere ich eine Variable mit dem Flag -v :

 $ echo | awk -v my_var=4 '{print "My var is " my_var}' My var is 4 

Übergeben Sie einfach die Umgebungsvariable als Parameter an das Flag -v . Zum Beispiel, wenn Sie diese Variable haben:

 $ VAR=3 $ echo $VAR 3 

Benutze es so:

 $ echo | awk -v env_var="$VAR" '{print "The value of VAR is " env_var}' The value of VAR is 3 

Natürlich können Sie den gleichen Namen vergeben, aber das $ wird nicht benötigt:

 $ echo | awk -v VAR="$VAR" '{print "The value of VAR is " VAR}' The value of VAR is 3 

Eine Anmerkung zu $ in awk : Im Gegensatz zu bash, Perl, PHP usw. ist es nicht Teil des Namens der Variablen, sondern ein Operator .

Awk und Gawk stellen das assoziative ENVIRON-Array bereit, das alle exportierten Umgebungsvariablen enthält. In Ihrem awk-Skript können Sie also ENVIRON [“VarName”] verwenden, um den Wert von VarName zu erhalten, vorausgesetzt, VarName wurde exportiert, bevor awk ausgeführt wurde.

Hinweis ENVIRON ist eine vordefinierte awk-Variable KEINE Shell-Umgebungsvariable.

Da ich nicht genug Reputation habe, um die anderen Antworten zu kommentieren, muss ich sie hier einbeziehen!

Die frühere Antwort, die $ ENVIRON zeigt, ist falsch – diese Syntax würde durch die Shell erweitert werden und wahrscheinlich dazu führen, dass nichts expandiert.

Weitere frühere Kommentare, dass C nicht auf die Umgebungsvariable zugreifen kann, sind falsch. Im Gegensatz zu dem, was oben gesagt wurde, kann C (und C ++) mit der function getenv (“VarName”) auf Umgebungsvariablen zugreifen. Viele andere Sprachen bieten einen ähnlichen Zugriff (z. B. Java: System.getenv (), Python: os.environ, Haskell System.Environment, …). Beachten Sie, dass der Zugriff auf Umgebungsvariablen in allen Fällen schreibgeschützt ist. Sie können eine Umgebungsvariable in einem Programm nicht ändern und diesen Wert an das aufrufende Skript zurückgeben.

Es gibt zwei Möglichkeiten, Variablen an awk : Eine Möglichkeit besteht darin, die Variable in einem Befehlszeilenargument zu definieren:

 $ echo ${UL[*]}|awk -F, -v NUSR=$NUSR '{print $NUSR}' SWATHI:SWATHI_NEW 

Eine andere Möglichkeit besteht darin, die Shell-Variable mithilfe von export in eine Umgebungsvariable zu konvertieren und die Umgebungsvariable aus dem ENVIRON Array ENVIRON :

 $ export NUSR $ echo ${UL[*]}|awk -F, '{print $ENVIRON["NUSR"]}' SWATHI:SWATHI_NEW 

Update 2016: Das OP hat kommagetrennte Daten und möchte ein Objekt aufgrund seines Index extrahieren. Der Index befindet sich in der Shell-Variablen NUSR . Der Wert von NUSR wird an awk , und der Dollar-Operator von awk extrahiert den Artikel.

Beachten Sie, dass es einfacher wäre, UL als ein Array von mehr als einem Element zu deklarieren und die Extraktion in bash durchzuführen und awk vollständig aus der Gleichung herauszunehmen. Dies verwendet jedoch 0-basierte Indizierung.

 UL=(AKHIL:AKHIL_NEW SWATHI:SWATHI_NEW) NUSR=1 echo ${UL[NUSR]} # prints SWATHI:SWATHI_NEW 

Es gibt einen anderen Weg, aber es könnte immense Verwirrung verursachen:

 $ VarName="howdy" ; echo | awk '{print "Just saying '$VarName'"}' Just saying howdy $ 

Sie verlassen also vorübergehend die Single-Quote-Umgebung (die normalerweise verhindern würde, dass die Shell ‘$’ interpretiert), um die Variable zu interpretieren und dann wieder darauf zurückzugreifen. Es hat den Vorteil, relativ kurz zu sein.

Nicht sicher, ob ich deine Frage verstehe.

Aber sagen wir, wir haben eine variable number=3 und wir wollen sie statt $3 , in awk können wir das mit folgendem Code machen

 results="100 Mbits/sec 110 Mbits/sec 90 Mbits/sec" number=3 speed=$(echo $results | awk '{print '"\$${number}"'}') 

Die Geschwindigkeitsvariable erhält also den Wert 110.

Hoffe das hilft.

Nein. Sie können den Wert einer Shell-Variablen an ein awk-Skript übergeben, genauso wie Sie den Wert einer Shell-Variablen an ein C-Programm übergeben können, aber Sie können nicht auf eine Shell-Variable in einem awk-Skript zugreifen in einem C-Programm. Wie C ist awk keine Shell. Siehe Frage 24 in der FAQ zu comp.unix.shell unter cfajohnson.com/shell/cus-faq-2.html#Q24.

Eine Möglichkeit, Ihren Code zu schreiben, wäre:

 UL="AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW" NUSR=$(awk -F, -v ul="$UL" 'BEGIN{print gsub(FS,""); exit}') echo "$NUSR" echo "$UL" | awk -F, -v nusr="$NUSR" '{print $nusr}' # could have just done print $NF 

aber seit deinem ursprünglichen Ausgangspunkt:

 UL=(AKHIL:AKHIL_NEW,SWATHI:SWATHI_NEW) 

Wenn Sie UL als ein Array mit nur einem Eintrag deklarieren, sollten Sie vielleicht überdenken, was Sie gerade versuchen, da Sie möglicherweise den falschen Ansatz haben.