If,then...fi 명령을 사용하여 사용자가 입력한 파일 형식이 올바른지 확인하는 방법은 무엇입니까? [복사]

If,then...fi 명령을 사용하여 사용자가 입력한 파일 형식이 올바른지 확인하는 방법은 무엇입니까? [복사]

계속하기 전에 사용자에게 올바른 스크립트 파일 형식을 입력했는지 알려주는 매우 기본적인 bash 스크립트를 만들려고 합니다. 예를 들어:

echo "Input .txt file here:"
read file
if $file = *.txt
    then 
    echo "File is in correct format."
    else
    echo "File is not in correct format. Please recheck your file."
    fi

이를 위해 무엇을 사용할 수 있습니까?

아래 명령은 작동하지 않으며 실제로 원하는 작업을 수행하는 대신 "기타"만 보고합니다.

$file = *.txt

답변1

물론 파일 확장자만으로는 파일 형식이 아닙니다. 이것은 누구나 간단한 작업으로 변경할 수 있는 텍스트입니다.

mv image.png word.txt

즉, 이 경우 간단히 다음 basename명령을 사용할 수 있습니다.

base=`basename "$file" .txt`
if test "$base" != "$file"
then
    echo "Success!"
else
    echo "Wrong extension..."
fi

답변2

다음 스크립트를 시도해 볼 수 있습니다.

if [ ".$(echo "$file"| cut -d. -f2)" == ".txt" ]
then
echo "File is in correct format."
else
echo "File is not in correct format. Please recheck your file."
fi

.파일 이름에 여러 점(점)이 있는 경우 다음 명령을 사용할 수 있습니다.

if [ ".$(echo "$file"| awk -F. '{print $NF}')" == ".txt" ]

답변3

좋습니다. 무엇을 하려는지 검토해 보겠습니다. 가장 먼저 알아야 할 것은 파일 이름이 " "인지 확인하고 싶지 않고 파일 이름이 " *.txt"인지 확인하고 싶다는 것입니다.패턴 일치" *.txt." 또한 Unix 스크립팅에서는 다양한 유형의 패턴을 접하게 되는데, 가장 일반적인 것은 와일드카드(또는 "glob") 패턴과 정규식(정규식 구문의 버전이 다양함)입니다. 여기에는 글로벌 패턴이 있습니다.

따라서 전역 패턴 일치를 수행하는 도구가 필요합니다. (글쎄, 다른 구문으로 패턴을 다시 작성할 수도 있고 확장자를 확인하는 데 완전히 다른 접근 방식을 취할 수도 있지만 지금은 glob 패턴 일치를 고수하겠습니다.)

둘째, 명령문에서 사용합니다 if. 명령문의 조건(및 if그 사이의 내용)은 다음과 같습니다.ifthen주문하다(또는 적어도 명령과 같은 것). 이 if명령문은 명령이 성공했는지 실패했는지에 따라 달라집니다. if가장 일반적으로 사용되는 명령 중 하나는 다음 [과 같은 명령문입니다.

if [ "$file" = "*.txt" ]; then

쉘 구문이나 이상한 괄호처럼 보이지만 [그렇지 않습니다. 이는 단지 일반 명령(대부분 동일함 test)입니다. 그러나 이는 마지막 인수가 " ]"(실제 닫는 대괄호가 아니라 일반 명령 인수임)여야 하고 나머지 인수를 논리 표현식으로 구문 분석하는 일반 명령입니다 . man [구문을 참조하세요 . 또한 "$file"두 가지 모두에 큰따옴표를 넣었으며 "*.txt"(일반적인 명령 인수로서) 파일 이름은 토큰화의 대상이 되고 둘 다 와일드카드 확장의 대상이 되어 표현식 구문에 혼란을 초래할 수 있기 때문입니다.

그러나 [패턴 일치는 수행되지 않습니다. 문자열 및 숫자(정수) 비교는 수행할 수 있지만 패턴 일치는 수행할 수 없습니다. 그러므로 우리는 다른 곳을 살펴봐야 합니다.

bash(또는 zsh 또는 심지어 ksh를 사용하지만아니요대시 또는 기타 좀 더 기본적인 쉘), 이와 [[ ]]달리 .[일반 명령 대신 쉘 구문은 본질적으로 [.할 수 있는=연산자와 패턴 매칭만약에오른쪽은 인용하지 않은 채로 둡니다. 즉, 리터럴 문자열 비교를 수행합니다.

if [[ "$file" = "*.txt" ]]; then

전역 모드 패치가 수행됩니다.

if [[ "$file" = *.txt ]]; then

(실제로 이러한 항목을 큰 따옴표로 묶을 필요는 없지만 $file변수 참조를 자동으로 큰 따옴표로 묶는 것을 선호합니다. 큰 따옴표를 사용하는 것이 거의 항상 안전하고 일반적으로 따옴표를 해제하는 것이 안전하지 않으며 예외를 기억하기가 더 쉽기 때문입니다. 인용해야 하는 예외보다 인용을 해제해야 하는 경우).

따라서 마지막 명령이 가능한 답변입니다.만약에지원되는 쉘을 사용하고 있습니다 [[ ]](즉, bash shebang을 사용하거나 일반 sh를 사용하지 않는 경우 #!/bin/bash) #!/usr/bin/env bash.

plain 을 사용한다면 sh규칙을 약간 변경해야 합니다. 일반적인 POSIX 셸에서 와일드카드 패턴 일치를 수행하는 가장 간단한 방법은 를 case사용하는 것 입니다 if. 왜냐하면 이것이 와일드카드 패턴 일치를 case위해 탄생했기 때문입니다.

case "$file" in
    *.txt )
        echo "File is in correct format." ;;

    * )
        "File is not in correct format. Please recheck your file." ;;
esac

패턴 *(이전 패턴과 일치하지 않는 모든 항목과 일치) 은 명령문 else의 절 처럼 작동합니다 if. 또한 )각 패턴과 일치하는 명령 사이, 그리고 ;;각 패턴 명령의 끝에서 구문에 익숙해지는 데 시간이 걸립니다 .

"Glob 패턴을 일치시키고 싶습니다"에서 "파일 이름이 '.txt'로 끝나는지 확인하고 싶습니다"로 전환하면 다른 옵션이 있습니다. 파일 이름 변수 확장 시 수정자를 사용하여 이를 달성하는 여러 가지(POSIX 표준) 방법이 있습니다. 예를 들어, ${var%pattern}일치 항목은 변수 값의 끝에서 제거됩니다 (pattern만약에일치합니다). 따라서 표준적인 방법은 파일 이름 끝에서 ".txt"를 제거하고 변경되는지 확인하는 것입니다. 그렇다면 ".txt"는 일치하고, 그렇지 않으면 일치하지 않습니다. 이와 같이:

if [ "$file" != "${file%.txt}" ]; then

!=".txt"가 끝에서 성공적으로 제거된 경우에만 문자열이 달라지므로 이는 같지 않음 테스트( )를 사용합니다 .

마지막 "."을 제거할 수도 있습니다. 파일 이름에 ${file##*.}(나머지가 "txt"인지 확인하기 위해) 여기에 문제가 있으면 파일 이름 "txt"가 일치한다고 생각합니다. 이런.

관련 정보