GNU/Linux >> Linux Esercitazione >  >> Linux

Come chiamare una funzione Bash nello script Bash all'interno di Awk?

Questo problema è correlato all'utilizzo della funzione della shell bash all'interno di AWK

Ho questo codice

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

e ho questo file:

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

L'output dovrebbe essere simile a questo:

smile
happy
laugh
angry
sad
happy    
sad
cry
sleep
quiet 

Il problema mi dice bash: emotion: command not found

Secondo il commento di akarilimano qui

questo non funziona sul mio Ubuntu 16.04. Questo è strano, perché prima funzionava “su Ubuntu 14.04.

Quindi come farlo nelle versioni più recenti?

Risposta accettata:

Probabilmente non è il modo migliore per affrontare il problema.

Da awk , tutto ciò che puoi fare è creare una riga di comando che system() passa a sh . Quindi, hai bisogno che gli argomenti siano formattati in sh sintassi.

Quindi avresti bisogno di:

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)
  }'

Qui citando $1 di awk quindi può essere tranquillamente incorporato nel sh riga di comando che finisce per eseguire bash con il contenuto di $1 come ultimo argomento, che poi lo passa a emotion .

Ciò presuppone il tuo sh e il tuo awk non rimuovere le variabili di ambiente speciali che bash utilizza per esportare funzioni (come pdksh e derivati ​​(come mksh ) per esempio, o dash dalla 0.5.8 che spiega il tuo problema 14.04 vs 16.04) e che la tua distribuzione non ha disabilitato le funzioni esportate in bash .

Se lo fa, potresti farlo come per ksh /zsh , e passare la definizione della funzione in un altro modo, ad esempio:

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 entrambi i casi, ciò significa eseguire una sh e una bash per questo. Forse puoi passare il $i per bash in un altro modo che tramite un system() che esegue due istanze di una shell ogni volta. Come:

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

Oppure fai la divisione delle parole in bash direttamente:

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

Linux
  1. In Bash, quando alias, quando script e quando scrivere una funzione?

  2. Come dividere una stringa nello script Bash

  3. Come creare e chiamare funzioni in Bash

  4. Script Bash - Come leggere l'input dell'utente

  5. Come implementare un timeout nella chiamata alla funzione di lettura?

Come eseguire uno script Bash {7 metodi}

Funzione Bash e come usarla {Variabili, argomenti, ritorno}

Come scrivere uno script Bash con esempi

Come eseguire uno script Bash

Come utilizzare Linux Bash Shell in Windows 10?

Come posso controllare la sintassi di uno script Bash senza eseguirlo?