我有这个简短的 if-then-else 脚本:
for INV in "$(ls np4178/*pdf)" ;\
do INVNUMB="$(pdfgrep -ho 'IN[0-9]{6,6}' $INV)" ; \
if [[ -z ${INVNUMB+x} ]]; \
then \
echo "\n$INVNUMB" ; \
else \
echo "wrong \n$INVNUMB" ; \
fi ; \
done
产生这个:
wrong \nIN353886
IN353897
IN353905
IN353910
IN353902
IN353864
IN353875
IN353840
IN353862
IN353922
IN353739
IN353876
IN353920
但是,如果我对声明进行更改,else
我会得到以下信息:
for INV in "$(ls np4178/*pdf)" ;\
do INVNUMB="$(pdfgrep -ho 'IN[0-9]{6,6}' $INV)" ; \
if [[ -z ${INVNUMB+x} ]]; \
then \
echo "\n$INVNUMB" ; \
else \
echo "\nIN000000" ; \
fi ; \
done
然后我只得到这个:
\nIN000000
为什么?更改子句中的文本字符串如何才能使else
脚本的整个行为和结果发生改变?
为什么换行符\n
在子句中打印为文字else
?
答案1
这段代码存在一些缺陷。
- 不解析
ls
。由于您已引用命令替换,因此每个结果都会INV
作为单个字符串传递。相反,您可以只循环遍历全局结果:
for inv in np4178/*pdf; do
您不需要该代码中的任何
;
或。\
事实上,它们的书写方式实际上是相互抵消的。;
是换行符分隔符,也是\
转义字符,在行尾使用时会转义新行。echo(通常)不会解释反斜杠转义符(
\n
),您可以使用echo -e
但是printf 比 echo 更好正如您已经发现的那样,您的测试构造正在检查变量是否是null 当你显然想检查它是否不是无效的
完全没有理由这样做
${INVNUMB+x}
。
您想要的代码可能如下所示:
for inv in np4178/*pdf; do
invnumb="$(pdfgrep -ho 'IN[0-9]{6,6}' "$inv")"
if [[ -n "$invnumb" ]]; then
printf '\n%s\n' "$invnumb"
else
printf '\n%s\n' "IN000000"
fi
done
答案2
感谢您的所有帮助。这非常有用。显然,我给出的示例并不是完整的脚本。而且我不理解用 括起环境变量的意义""
,所以吸取了教训。这是我理解这个问题的早期尝试,所以我对我到底想要完成什么感到有些困惑。
我将其发布为正确设置代码格式的答案。以下或多或少是我最终得到的结果:
for INV in $(ls -1 $SRCDIR/HP3000-INV*pdf)
# search files for IN###### and return only first occurrence of match
do INVNUMB="$(pdfgrep -h -o -m 1 'IN[0-9]{6,6}' $INV)"
if [[ -n ${INVNUMB} ]]; \
then
# prepend the invoice number to the file name
# and move renamed file to xfr directory
mv -f $INV $(dirname $INV)"/"$TODAY"/"$INVNUMB"-"$(basename $INV)
fi
done