GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie rufe ich eine Bash-Funktion in einem Bash-Skript in Awk auf?

Dieses Problem steht im Zusammenhang mit der Verwendung der Bash-Shell-Funktion in AWK

Ich habe diesen Code

#!/bin/bash

function emotion() {
            #here is function code end with return value...
            echo $1
}

export -f emotion

#I've put all animals in array
animalList=($(awk '{print $1}' animal.csv)) 

#loop  array and grep all the lines form the file
for j in ${animalList[@]}
do
  :                                                     #here I'am running a bash script calling emotion function 
   grep $j animal.csv | awk '{for(i=2;i<=NF;i++){system("bash -c '\''emotion "$i"'\''")}}'
done

und ich habe diese Datei:

cat    smile    happy   laugh
dog    angry    sad
mouse  happy    
wolf   sad      cry
fox    sleep    quiet 

Die Ausgabe sollte so aussehen:

smile
happy
laugh
angry
sad
happy    
sad
cry
sleep
quiet 

Das Problem, das es mir mitteilt, bash: emotion: command not found

Laut akarilimanos Kommentar hier

Dies funktioniert nicht auf meinem Ubuntu 16.04. Das ist seltsam, weil es früher „unter Ubuntu 14.04“ funktionierte.

Wie macht man das also in neueren Versionen?

Akzeptierte Antwort:

Das ist wahrscheinlich nicht der beste Weg, um das Problem anzugehen.

Von awk , alles, was Sie tun können, ist eine Befehlszeile zu erstellen, die system() geht an sh über . Sie müssen also die Argumente im sh formatieren Syntax.

Sie benötigen also:

emotion() {
  echo "$i"
}
export -f emotion
awk -v q="'" '
  function sh_quote(s) {
    gsub(q, q "\\" q q, s)
    return q s q
  }
  {
    for (i = 2; i <= NF; i++)
      status = system("bash -c '\''emotion \"[email protected]\"'\'' bash " sh_quote($1)
  }'

Hier wird $1 von awk zitiert damit es sicher in sh eingebettet werden kann Befehlszeile, die schließlich bash ausführt mit dem Inhalt von $1 als letztes Argument, das es dann an emotion übergibt .

Das setzt Ihr sh voraus und Ihr awk Entfernen Sie nicht die speziellen Umgebungsvariablen, die bash verwendet, um Funktionen zu exportieren (wie pdksh und Derivate (wie mksh ) zum Beispiel oder dash seit 0.5.8, was Ihr Problem zwischen 14.04 und 16.04 erklärt), und dass Ihre Distribution exportierte Funktionen in bash nicht deaktiviert hat .

Wenn ja, könnten Sie es wie für ksh machen /zsh , und übergeben Sie die Definition der Funktion auf andere Weise, wie zum Beispiel:

CODE=$(typeset -f emotion) awk -v q="'" '
  function sh_quote(s) {
    gsub(q, q "\\" q q, s)
    return q s q
  }
  {
    for (i = 2; i <= NF; i++)
      status = system("bash -c '\''eval \"$CODE\"; emotion \"[email protected]\"'\'' bash " \
                      sh_quote($1)
  }'

In beiden Fällen bedeutet das, dass ein sh und ein bash dafür ausgeführt werden. Vielleicht kannst du den $i weitergeben zu bash anders als über ein system() die jedes Mal zwei Instanzen einer Shell ausführt. Wie:

awk '{for (i=2; i<=NF; i++) printf "%s\0" $i}' |
  while IFS= read -r i; do
    emotion "$i"
  done

Oder führen Sie die Worttrennung in bash durch direkt:

unset IFS
while read -ra fields; do
  for i in "${fields[@]:1}"; do
    emotion "$i"
  done
done

Linux
  1. Wie werden Parameter eingestellt, wenn Bash-Skript an Bash übergeben wird?

  2. So erstellen und rufen Sie Funktionen in Bash auf

  3. Bash-Skript - So lesen Sie Benutzereingaben

  4. Aufrufen von C-Funktionen in C++, C++-Funktionen in C (C und C++ mischen)

  5. Wie kann man Bash-Skripte in Vim hervorheben?

So führen Sie ein Bash-Skript aus {7 Methoden}

Bash-Funktion und Verwendung {Variablen, Argumente, Rückgabe}

So schreiben Sie ein Bash-Skript mit Beispielen

So führen Sie ein Bash-Skript aus

Wie verwende ich die Linux-Bash-Shell in Windows 10?

Wie überprüfe ich die Syntax eines Bash-Skripts, ohne es auszuführen?