if 문에서 와일드카드가 해석되지 않음

if 문에서 와일드카드가 해석되지 않음

현재 아래 스크립트를 작성 중입니다. 이 코드는 사용자가 입력한 파일 이름을 찾기 위해 특정 디렉터리를 찾습니다. 스크립트는 먼저 입력 파일이 gzip인지 확인하고, 그렇다면 해당 확인을 실행합니다. 파일이 gzip으로 압축되지 않은 경우 호환되지 않는 파일 텍스트로 응답합니다.

내가 겪고 있는 문제는 온라인 상태입니다 7. 파일 확장자와 상관없이 최종 출력으로 호환되지 않는 파일이 수신됩니다.

#!/bin/bash
DATE=$(date +%Y-%m-%d)
L0_Report_Generator=("/home/ubuntu/$gzip_file")
echo -n "Enter File Directory:"$gzip_file 
read  $gzip_file
for gzip_file in {$L0_Report_Generator}; do
  if [[ $gzip_file = "test_sub"*"gz" ]] #Check file extension for gzip compression
      then
         gunzip $gzip_file
         echo "file Level 0 QC Check"
         echo ${DATE}
         echo "File Header"
         cat $gzip_file | head
         echo "Total Records"
         cat $gzip_file | wc -l
         echo "File Unique Records Size"
         cat $L0_Report_Generator | sort -u | wc -l
         rm $gzip_file 
    else [[ $gzip_file != "test_sub"*"gz" ]] #If file is anything other than .gz and csv - rort will not run
       then
         echo "incompatible file"
         fi
done

답변1

if 문 내부에서 와일드카드 표현식을 사용하여 ".gz" 파일 이름 확장자를 확인하려면 다음과 같은 표현식을 사용합니다.

if [[ "${gzip_file}" = *.gz ]]; then echo true; else echo false; fi

테스트하는 방법은 다음과 같습니다.

if [[ "file.gz" = *.gz ]]; then echo true; else echo false; fi

그리고:

if [[ "file.txt" = *.gz ]]; then echo true; else echo false; fi

첫 번째 예에서는 true출력으로 생성하고 두 번째 예에서는 를 생성합니다 false.

이제 코드를 살펴보겠습니다. if 문에는 대신 다음과 같은 조건식이 있습니다.

[[ $gzip_file = "test_sub"*"gz" ]]

특히 일치 패턴의 하위 문자열로 "test_sub"를 포함하고 있습니다. 그것을 제거해보십시오.

답변2

파일 확장자 확인에 대해 @igal이 말한 것 외에도 변수 구문 및 사용법에 많은 오류가 있습니다. 3번째 줄부터 시작하세요:

L0_Report_Generator=("/home/ubuntu/$gzip_file")

변수는 gzip_file아직 설정되지 않았으므로 $gzip_file쉘이 확장할 때 아무것도 대체되지 않습니다. 또한 의 괄호는 var=(something)일반 변수 대신 배열을 할당하는데 이 경우에는 의미가 없습니다.

네 번째 줄인 에는 echo -n "Enter File Directory:"$gzip_file변수 와 동일한 문제가 있습니다 gzip_file. 또한 echo -n예측할 수 없고 명령의 다른 버전에서 다른 작업을 수행하는 문제도 있습니다 echo. 줄 바꿈 없이 문자열을 인쇄하려면 를 사용하는 것이 훨씬 낫지 printf "%s" "string to print"만 이 경우에는 더 나은 옵션이 있으므로 잠시 후에 살펴보겠습니다.

다섯 번째 줄인 은 read $gzip_file사용자 입력을 변수로 읽어들이기 위한 것으로 보이지만 gzip_file실제로는 그렇지 않습니다. 쉘에서는 $변수 이름 앞에 변수 이름을 넣으면얻다변수의 현재 값. 여기, 당신이 원하는세트그러니까 넌 떠나야 해$ off: 를 그대로 두어야 합니다 read gzip_file. 하지만 그건 내가 할 일이 아닙니다. 명령 echo의 일부로 프롬프트(4행에 있음)를 포함하겠습니다 read.

read -p "Enter File Directory:" gzip_file

좋습니다. 이제 6번째 줄에 대해 설명합니다.

for gzip_file in {$L0_Report_Generator}; do

이렇게 설정하는 것 같더라구요gzip_file 다시(우리가 방금 값을 대체read .) 실제로 여기에서 설정하려고 하는데 gzip_file이전 변수 참조가 실제로 다른 변수였어야 합니까(아마도 gzip_dir)?

또한 그 in부분은 의미가 없습니다. 변수를 사용하려고 하시는 것 같은데 L0_Report_Generator, 그런 경우에는 여는 중괄호를 사용해야 합니다.~ 후에달러 기호. 하지만 그것도 전혀 말이 되지 않습니다. 왜냐하면${L0_Report_Generator} (이것이 무엇을 해야 하는지 제가 이해한다면) 단지 디렉토리에 대한 경로일 뿐이기 때문입니다. for ... in디렉토리의 내용을 반복하지 않고 목록을 반복합니다.단어, 좋다 for var in word1 word2 "word 3 which has several spaces in it" word4; do. 디렉토리의 파일 목록을 얻으려면 와일드카드를 사용해야 합니다. 예를 들어, for var in dir/*; do쉘은 와일드카드가 포함된 파일 패턴을 각각 단어로 처리되는 일치하는 파일 목록으로 확장하고 반복합니다. . .dir/*.gz

DATE기타 세 가지 참고 사항: 쉘이나 일부 유틸리티에 특별한 의미를 갖는 다양한 대문자 환경 변수와의 충돌을 피하기 위해 와 같은 대문자 변수 이름을 사용하지 않는 것이 좋습니다 . 또한 예상치 못한 구문 분석 문제를 방지하려면 항상 변수 참조를 큰따옴표로 묶으십시오(예: "$var"그냥 대신 사용). $var그리고 else절에는 테스트가 없으므로 using은 else [[ some test ]]의미가 없습니다(그리고 thenafter를 갖는 else것은 구문 오류입니다).

따라서 스크립트가 수행해야 하는 작업을 이해했다면 스크립트 시작 부분을 다음으로 바꾸는 것이 좋습니다.

#!/bin/bash
date=$(date +%Y-%m-%d)    # Note lowercase variable
read -p "Enter File Directory:" gzip_dir
L0_Report_Generator="/home/ubuntu/$gzip_dir"

for gzip_file in "${L0_Report_Generator}"/*.gz; do

...그리고 (위의 .gz 패턴이 원하는 경우) 와일드카드 패턴은 .gz 파일만 나열하므로 .gz 확장명이 있는지 if여부를 확인할 필요가 없습니다.$gzip_file

한 가지 더 참고사항:shellcheck.net쉘 스크립트의 기본적인 오류를 지적하는 데 매우 유용합니다. 제가 지적한 내용을 많이 놓쳤지만 then(처음에는 놓쳤던) 길을 잃었습니다.

관련 정보