我有这个代码
#!/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
Run Code Online (Sandbox Code Playgroud)
我有这个文件:
cat smile happy laugh
dog angry sad
mouse happy
wolf sad cry
fox sleep quiet
Run Code Online (Sandbox Code Playgroud)
输出应该是这样的:
smile
happy
laugh
angry
sad
happy
sad
cry
sleep
quiet
Run Code Online (Sandbox Code Playgroud)
它告诉我的问题bash: emotion: command not found
根据 akarilimano 的评论这里
这在我的 Ubuntu 16.04 上不起作用。这很奇怪,因为它曾经在“Ubuntu 14.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 \"$@\"'\'' bash " sh_quote($1)
}'
Run Code Online (Sandbox Code Playgroud)
这里引用 awk,$1
这样它就可以安全地嵌入到命令行中,最终以最后一个参数的内容sh
运行,然后将其传递给.bash
$1
emotion
假设您sh
和您awk
没有删除bash
用于导出函数的特殊环境变量(例如pdksh
和 衍生物(例如mksh
),或者dash
从 0.5.8 开始,这解释了您的 14.04 与 16.04 问题),并且您的发行版没有禁用导出功能bash
。
如果是这样,您可以像 for 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 \"$@\"'\'' bash " \
sh_quote($1)
}'
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,这都意味着为其运行一个 sh 和一个 bash。也许您可以将 a 传递$i
给bash
其他方式,而不是通过 asystem()
每次执行 shell 的两个实例。喜欢:
awk '{for (i=2; i<=NF; i++) printf "%s\0" $i}' |
while IFS= read -r i; do
emotion "$i"
done
Run Code Online (Sandbox Code Playgroud)
或者直接进行分词bash
:
unset IFS
while read -ra fields; do
for i in "${fields[@]:1}"; do
emotion "$i"
done
done
Run Code Online (Sandbox Code Playgroud)