GNU/Linux >> Znalost Linux >  >> Linux

Jak volat funkci Bash ve skriptu Bash uvnitř Awk?

Tento problém souvisí s používáním funkce bash shell uvnitř AWK

Mám tento kód

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

a mám tento soubor:

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

Výstup by měl vypadat takto:

smile
happy
laugh
angry
sad
happy    
sad
cry
sleep
quiet 

Problém, který mi říká bash: emotion: command not found

Podle komentáře akarilimana zde

toto nefunguje na mém Ubuntu 16.04. To je zvláštní, protože to dříve fungovalo „na Ubuntu 14.04.

Jak to tedy udělat v novějších verzích?

Přijatá odpověď:

To pravděpodobně není nejlepší způsob, jak k problému přistupovat.

Z awk , vše, co můžete udělat, je vytvořit příkazový řádek, který system() přechází na sh . Takže potřebujete, aby byly argumenty formátovány v sh syntaxe.

Takže budete potřebovat:

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

Zde cituji $1 awk takže jej lze bezpečně vložit do sh příkazový řádek, který skončí spuštěním bash s obsahem $1 jako poslední argument, který jej poté předá emotion .

To předpokládá vaše sh a vaše awk neodstraňujte speciální proměnné prostředí, které bash používá k exportu funkcí (jako pdksh a deriváty (například mksh ) například nebo dash od 0.5.8, což vysvětluje váš problém 14.04 vs 16.04), a že vaše distribuce nezakázala exportované funkce v bash .

Pokud ano, můžete to udělat jako pro ksh /zsh a předejte definici funkce jiným způsobem, například:

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

V obou případech to znamená spustit jeden sh a jeden bash. Možná můžete předat $i na bash nějakým jiným způsobem než přes system() který pokaždé provede dvě instance shellu. Jako:

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

Nebo proveďte rozdělení slov v bash přímo:

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

Linux
  1. Jak rozdělit řetězec ve skriptu Bash

  2. Jak vytvářet a volat funkce v Bash

  3. Bash Script - Jak číst uživatelský vstup

  1. Jak volat funkci C v C++, funkci C++ v C (Mix C a C++)

  2. Jak implementovat časový limit ve volání funkce čtení?

  3. spuštění php skriptu (funkce php) v linux bash

  1. V Bash, kdy alias, kdy skript a kdy napsat funkci?

  2. Jak ladit Bash skript?

  3. Jak spustit bash skript?