この問題は、AWK内でのbashシェル関数の使用に関連しています
私はこのコードを持っています
#!/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
そして私はこのファイルを持っています:
cat smile happy laugh
dog angry sad
mouse happy
wolf sad cry
fox sleep quiet
出力は次のようになります:
smile
happy
laugh
angry
sad
happy
sad
cry
sleep
quiet
bash: emotion: command not found
と表示される問題
ここでのakarilimanoのコメントによると
これは私のUbuntu16.04では機能しません。以前は「Ubuntu14.04で」動作していたため、これは奇妙なことです。
では、新しいバージョンでそれを行う方法は?
承認された回答:
それはおそらく問題に取り組むための最良の方法ではありません。
awk
から 、できることは、system()
というコマンドラインを作成することだけです。 sh
に渡されます 。したがって、引数はsh
でフォーマットする必要があります 構文。
したがって、次のものが必要になります:
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)
}'
ここでawkの$1
を引用します そのため、sh
に安全に埋め込むことができます 最終的にbash
を実行するコマンドライン $1
の内容で 最後の引数として、それをemotion
に渡します 。
それはあなたのsh
を前提としています そしてあなたのawk
bash
する特別な環境変数を削除しないでください 関数のエクスポートに使用します(pdksh
など) および派生物(mksh
など) )たとえば、またはdash
14.04と16.04の問題を説明する0.5.8以降)、およびディストリビューションがbash
でエクスポートされた関数を無効にしていないこと 。
もしそうなら、あなたはksh
のようにそれをすることができます / zsh
、および関数の定義を次のような別の方法で渡します。
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)
}'
どちらの場合も、それは1つのshと1つのbashを実行することを意味します。たぶんあなたは$i
を渡すことができます bash
へ system()
以外の方法 毎回シェルの2つのインスタンスを実行します。いいね:
awk '{for (i=2; i<=NF; i++) printf "%s\0" $i}' |
while IFS= read -r i; do
emotion "$i"
done
または、bash
で単語を分割します 直接:
unset IFS
while read -ra fields; do
for i in "${fields[@]:1}"; do
emotion "$i"
done
done