BASH if-then-else 동작에 대한 설명을 원합니다.

BASH if-then-else 동작에 대한 설명을 원합니다.

다음과 같은 짧은 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

이 코드에는 몇 가지 결함이 있습니다.

  1. 파싱되지 않음ls. 명령 대체를 인용했으므로 각 결과는 INV단일 문자열로 전달됩니다. 대신 전역 결과를 반복할 수 있습니다.
for inv in np4178/*pdf; do
  1. 이 코드에는 또는 가 필요하지 않습니다 ;. \사실, 그것들이 쓰여지는 방식은 실제로 서로를 상쇄합니다. ;줄 바꿈 구분 기호이자 \줄 끝에서 사용될 때 줄 바꿈을 이스케이프하는 이스케이프 문자입니다.

  2. echo(보통)는 백슬래시 이스케이프 문자( )를 해석하지 않습니다. \n사용할 수는 echo -e있지만printf가 echo보다 낫습니다.

  3. 이미 발견했듯이 테스트 구성은 변수가null인지 확인하고 싶은 경우아니요유효하지 않은

  4. 이렇게 할 이유가 전혀 없습니다 ${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

관련 정보