简体   繁体   English

在shell脚本变量中执行bash命令时出错

[英]errors executing bash command in shell script variable

In terminal(bash) the following command produces the correct output (an integer) 在terminal(bash)中,以下命令产生正确的输出(整数)

ls -l | grep '.json' | grep -v 'fit-report.json' | wc -l

which correctly returns 13. 正确返回13。

Trying the same in a shell script: 在shell脚本中尝试相同的操作:

number_reports= $(ls -l | grep '.json' | grep -v 'fit-report.json' | wc -l)
echo "number of reports is $number_reports"

produces runtime errors: 产生运行时错误:

line 1: ls -l | grep '.json' | grep -v 'fit-report.json' | wc -l: command not found
number of reports is 

I've tried it without the $(..) bracketing as well as storing the var as a string and executing it in another variable, but I couldn't get that working either. 我已经尝试过在没有$(..)括号的情况下进行尝试,以及将var存储为字符串并在另一个变量中执行它,但是我也无法正常工作。

Remove spaces around = : 删除=周围的空格:

number_reports=$(ls -l | grep '.json' | grep -v 'fit-report.json' | wc -l)

Though parsing ls output is not recommended as your file names can have spaces and newlines. 尽管不建议解析ls输出,因为您的文件名可以包含空格和换行符。

UPDATE: 更新:

Better to use this script to get your count: 最好使用此脚本来获取数量:

number_reports=0
while read -d ''; do
    ((number_reports++))
done < <(find . -maxdepth 1 -name "*.json" -a ! -name "fit-report.json" -print0)

echo "number_reports=$number_reports"

If I understand correctly, you want the number of filenames F in current directory that end with .json but such that Ffit-report.json (even though you didn't exactly express this with your chain of grep s and pipes). 如果我理解正确,则您希望当前目录中以.json结尾的文件名F的数量,但要使Ffit-report.json (即使您未使用grep s和管道链准确地表示出来)。

A straightforward pure bash way, using (extended) globs and arrays: 一种简单的纯bash方式,使用(扩展的)glob和数组:

shopt -s nullglob extglob
filenames=( !(fit-report).json )
printf "number of reports is %d\n" "${#filenames[@]}"

(no spaces around the = sign). (在=号周围没有空格)。

The use of shopt -s nullglob is so that the glob expands to nothing if there are no matches (otherwise it expands to itself verbatim) and shopt -s extglob to turn on the extended globs. 使用shopt -s nullglob是,如果没有匹配项,则glob扩展shopt -s extglob (否则逐字扩展为自身),而使用shopt -s extglob可以打开扩展的glob。

Then we build an array filenames that contains all the file names that end with .json , ignoring the file name fit-report (that's the !(fit-report) part). 然后,我们构建一个数组filenames ,其中包含所有以.json结尾的文件名,而忽略文件名称fit-report (这是!(fit-report)部分)。

Then we print the number of elements in this array (the number of elements in array filenames is ${#filenames[@]} ). 然后,我们打印此数组中的元素数(数组filenames的元素数为${#filenames[@]} )。

If you really want the number of reports in a variable: 如果您确实想要一个变量中的报告数量:

number_reports=${#filenames[@]}

(with no spaces around the = sign). (在=号周围没有空格)。

Note. 注意。 this will not count the “hidden” filenames (eg, .hidden.json ), unless you shopt -s dotglob . 除非您.hidden.json shopt -s dotglob ,否则这不会计算“隐藏”的文件名(例如.hidden.json )。

Note. 注意。 Do not parse the output of ls . 不要解析ls的输出

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM