파일 이름의 확장자를 가져옵니다.

파일 이름의 확장자를 가져옵니다.

Bash에서 파일 확장자를 얻는 방법은 무엇입니까? 내가 시도한 것은 다음과 같습니다.

filename=`basename $filepath`
fileext=${filename##*.}

이렇게 하면 bz2경로에서 확장을 얻을 수 있지만 /dir/subdir/file.bz2경로에 문제가 있습니다 /dir/subdir/file-1.0.tar.bz2.

가능하다면 bash만 사용하고 외부 프로그램은 사용하지 않는 솔루션을 선호합니다.

내 문제를 명확하게 설명하기 위해 단 하나의 명령으로 특정 아카이브를 추출할 수 있는 bash 스크립트를 만들고 있습니다 extract path_to_file. 파일을 추출하는 방법은 압축 또는 아카이브 유형(.tar.gz, .gz, .bz2 등)을 확인하여 스크립트에 의해 결정됩니다. 나는 이것이 문자열 조작을 포함해야 한다고 생각합니다. 예를 들어 확장을 얻으면 그 앞에 해당 문자열이 있는지 .gz확인해야 합니다 . 그렇다면 확장은 ..tar.gz.tar.gz

답변1

확장자를 두 번 추출하는 대신 파일 이름만 패턴 일치하여 문제를 단순화할 수 있습니다.

case "$filename" in
    *.tar.bz2) bunzip_then_untar ;;
    *.bz2)     bunzip_only ;;
    *.tar.gz)  untar_with -z ;;
    *.tgz)     untar_with -z ;;
    *.gz)      gunzip_only ;;
    *.zip)     unzip ;;
    *.7z)      do something ;;
    *)         do nothing ;;
esac

답변2

파일 이름이 이면 file-1.0.tar.bz2확장자는 입니다 bz2. 확장자( fileext=${filename##*.})를 추출하는 데 사용한 방법은 완전히 유효합니다.

확장자가 or 인지 tar.bz2아닌지 를 어떻게 결정합니까 ? 먼저 이 질문에 답해야 합니다. 그러면 어떤 쉘 명령이 귀하의 사양과 일치하는지 확인할 수 있습니다.bz20.tar.bz2

  • 가능한 사양 중 하나는 확장자가 문자로 시작해야 한다는 것입니다. 이 경험적 방법은 다음 7z과 같은 일부 일반적인 확장에서는 실패합니다. 이것은 bash/ksh/zsh 구현입니다:

    basename=$filename; fileext=
    while [[ $basename = ?*.* &&
             ( ${basename##*.} = [A-Za-z]* || ${basename##*.} = 7z ) ]]
    do
      fileext=${basename##*.}.$fileext
      basename=${basename%.*}
    done
    fileext=${fileext%.}
    

    POSIX 이식성을 위해서는 패턴 일치를 위한 문을 사용해야 합니다 case.

    while case $basename in
            ?*.*) case ${basename##*.} in [A-Za-z]*|7z) true;; *) false;; esac;;
            *) false;;
          esac
    do …
    
  • 또 다른 가능한 사양은 특정 확장이 인코딩을 나타내고 추가 제거가 필요함을 나타내는 것입니다. 이것은 bash/ksh/zsh 구현입니다( shopt -s extglobbash 및 setopt ksh_globzsh에서 필요).

    basename=$filename
    fileext=
    while [[ $basename = ?*.@(bz2|gz|lzma) ]]; do
      fileext=${basename##*.}.$fileext
      basename=${basename%.*}
    done
    if [[ $basename = ?*.* ]]; then
      fileext=${basename##*.}.$fileext
      basename=${basename%.*}
    fi
    fileext=${fileext%.}
    

    0고려 되오니 참고하시기 바랍니다 file-1.0.gz.

관련 구조물에 위치 ${VARIABLE##SUFFIX}POSIX, 따라서 ash, bash, ksh 또는 zsh와 같은 골동품이 아닌 Bourne 스타일 쉘에서 작동합니다.

답변3

$ echo "thisfile.txt"|awk -F . '{print $NF}'

이에 대한 의견은 다음과 같습니다.http://liquidat.wordpress.com/2007/09/29/short-tip-get-file-extension-in-shell-script/

답변4

어느 날 저는 다음과 같은 까다로운 함수를 만들었습니다.

# args: string how_many
function get_last_letters(){ echo ${1:${#1}-$2:$2}; }
function cut_last_letters(){ echo ${1:0:${#1}-$2}; }

나는 이 간단한 접근 방식이 확장이 관련된 경우뿐만 아니라 많은 상황에서 매우 유용하다는 것을 알았습니다.

확장자를 확인하려면 -간단하고 신뢰할 수 있음

~$ get_last_letters file.bz2 4
.bz2
~$ get_last_letters file.0.tar.bz2 4
.bz2

컷오프 확장의 경우:

~$ cut_last_letters file.0.tar.bz2 4
file.0.tar

확장자를 변경하려면:

~$ echo $(cut_last_letters file.0.tar.bz2 4).gz
file.0.tar.gz

또는 "편리한 기능을 선호하는 경우:

~$ function cut_last_letters_and_add(){ echo ${1:0:${#1}-$2}"$3"; }
~$ cut_last_letters_and_add file.0.tar.bz2 4 .gz
file.0.tar.gz

PS 이 기능이 마음에 들거나 유용하다고 생각되면 이 게시물을 참조하세요 :) (그리고 댓글을 남기고 싶습니다).

관련 정보