![BASH if-then-else 동작에 대한 설명을 원합니다.](https://linux55.com/image/191063/BASH%20if-then-else%20%EB%8F%99%EC%9E%91%EC%97%90%20%EB%8C%80%ED%95%9C%20%EC%84%A4%EB%AA%85%EC%9D%84%20%EC%9B%90%ED%95%A9%EB%8B%88%EB%8B%A4..png)
다음과 같은 짧은 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