현재 다음 스크립트를 작성 중입니다. 이 코드는 사용자가 디렉토리에 입력한 파일 이름을 찾습니다. 스크립트는 먼저 입력 파일이 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
실제로는 그렇지 않습니다. 쉘에서는 $
변수명 앞에 붙이면 ,얻다변수의 현재 값입니다. 여기 당신이 원하는놓다그래서 당신은 다음을 유지해야 합니다 $
: 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 ]]
의미가 없습니다(그리고 then
after는 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
(처음에는 놓쳤습니다).