次のような短い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