GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana Memanggil Fungsi Bash Dalam Skrip Bash Di Dalam Awk?

Masalah ini terkait dengan Menggunakan fungsi bash shell di dalam AWK

Saya punya kode ini

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

dan saya memiliki file ini:

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

Outputnya akan seperti ini:

smile
happy
laugh
angry
sad
happy    
sad
cry
sleep
quiet 

Masalah ini memberi tahu saya bash: emotion: command not found

Menurut komentar akarilimano di sini

ini tidak berfungsi di Ubuntu 16.04 saya. Ini aneh, karena dulu berfungsi “di Ubuntu 14.04.

Jadi bagaimana melakukannya di versi yang lebih baru?

Jawaban yang Diterima:

Itu mungkin bukan cara terbaik untuk mengatasi masalah.

Dari awk , yang dapat Anda lakukan hanyalah membuat baris perintah yang system() lolos ke sh . Jadi, Anda memerlukan argumen untuk diformat dalam sh sintaks.

Jadi, Anda memerlukan:

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

Di sini mengutip $1 awk's sehingga dapat disematkan dengan aman di sh baris perintah yang akhirnya menjalankan bash dengan isi $1 sebagai argumen terakhir, yang kemudian diteruskan ke emotion .

Itu mengasumsikan sh . Anda dan awk . Anda jangan hapus variabel lingkungan khusus yang bash gunakan untuk mengekspor fungsi (seperti pdksh dan turunannya (seperti mksh ) lakukan misalnya, atau dash sejak 0.5.8 yang menjelaskan masalah 14.04 vs 16.04 Anda), dan bahwa distribusi Anda belum menonaktifkan fungsi yang diekspor di bash .

Jika ya, Anda bisa melakukannya seperti untuk ksh /zsh , dan berikan definisi fungsi dengan cara lain, seperti:

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

Dalam kedua kasus, itu berarti menjalankan satu sh dan satu bash untuk itu. Mungkin Anda bisa melewati $i ke bash cara lain selain melalui system() yang mengeksekusi dua instance shell setiap kali. Seperti:

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

Atau lakukan pemisahan kata di bash langsung:

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

Linux
  1. Di Bash, Kapan Alias ​​​​Kapan Skrip, Dan Kapan Menulis Fungsi?

  2. Bagaimana Cara Men-debug Skrip Bash?

  3. Bagaimana Cara Mengatur Parameter Saat Pipa Bash Script Ke Bash?

  1. Bagaimana Memanggil Script Shell Lain Seperti Subrutin?

  2. Cara Memisahkan String dalam Skrip Bash

  3. Cara Memanggil Fungsi C di C++, Fungsi C++ di C (Campuran C dan C++)

  1. Bagaimana cara menyorot skrip Bash di Vim?

  2. Bagaimana cara meneruskan parameter ke skrip Bash?

  3. Bagaimana cara menjalankan skrip bash?