it-swarm-ko.tech

파일 이름으로 확장자를 잡아

Bash에서 파일 확장자를 어떻게 얻습니까? 내가 시도한 것은 다음과 같습니다.

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

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

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

내 질문을 명확히하기 위해 extract path_to_file의 단일 명령으로 주어진 아카이브를 추출하는 bash 스크립트를 작성했습니다. 파일을 추출하는 방법은 압축 또는 보관 유형을 확인하여 스크립트에 의해 결정됩니다. .tar.gz, .gz, .bz2 등이 될 수 있습니다. 예를 들어 확장자가 .gz 그런 다음 .tar 앞에 문자열 .gz이 있는지 확인해야합니다. 확장명은 .tar.gz이어야합니다.

36
uray

파일 이름이 file-1.0.tar.bz2 인 경우 확장자는 bz2입니다. 확장명 (fileext=${filename##*.})을 추출하는 데 사용하는 방법은 완벽하게 유효합니다 ¹.

확장명이 tar.bz2 또는 bz2가 아닌 0.tar.bz2가되도록하려면 어떻게합니까? 이 질문에 먼저 답해야합니다. 그런 다음 사양에 맞는 Shell 명령을 알아낼 수 있습니다.

  • 가능한 사양 중 하나는 확장자가 문자로 시작해야한다는 것입니다. 이 휴리스틱은 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 구현은 다음과 같습니다 (bash에서 shopt -s extglob 및 zsh에서 setopt ksh_glob 필요).

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

    이것은 0file-1.0.gz의 확장으로 간주합니다.

¹ ${VARIABLE##SUFFIX} 및 관련 구문은 POSIX 에 있으므로 ash, bash, ksh 또는 zsh.

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

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
25
glenn jackman
$ echo "thisfile.txt"|awk -F . '{print $NF}'

여기에 대한 의견 : http://liquidat.wordpress.com/2007/09/29/short-tip-get-file-extension-in-Shell-script/

7
Chris

여기에 내 장면이 있습니다 : 점을 줄 바꿈으로 변환하고 tail를 통해 파이프하고 마지막 줄을 얻으십시오.

$> TEXT=123.234.345.456.456.567.678
$> echo $TEXT | tr . \\n | tail -n1
678
2
Michael Bar-Sinai
echo ${filename#$(echo $filename | sed 's/\.[^[:digit:]].*$//g;')}

예를 들면 다음과 같습니다.

% echo $filename
2.6.35-zen2.patch.lzma
% echo ${filename#$(echo $filename | sed 's/\.[^[:digit:]].*$//g;')}
.patch.lzma
0
Maciej Piechotka

어느 날 나는 그 까다로운 기능을 만들었습니다.

# 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

추신 해당 기능이 마음에 들거나 전체 기능을 사용한 것으로 확인 된 경우이 게시물을 참조하십시오. :).

0

jackman case-based answer은 꽤 훌륭하고 이식 가능하지만 변수의 파일 이름과 확장자를 원한다면이 솔루션을 찾았습니다.

INPUTFILE="$1"
INPUTFILEEXT=$( echo -n "$INPUTFILE" | rev | cut -d'.' -f1 | rev )
INPUTFILEEXT=$( echo -n $INPUTFILEEXT | tr '[A-Z]' '[a-z]' ) # force lowercase extension
INPUTFILENAME="`echo -n \"$INPUTFILE\" | rev | cut -d'.' -f2- | rev`"

# fix for files with multiple extensions like "gbamidi-v1.0.tar.gz"
INPUTFILEEXT2=$( echo -n "$INPUTFILENAME" | rev | cut -d'.' -f1 | rev )
if [ "$INPUTFILEEXT2" = "tar" ]; then
    # concatenate the extension
    INPUTFILEEXT="$INPUTFILEEXT2.$INPUTFILEEXT"
    # update the filename
    INPUTFILENAME="`echo -n \"$INPUTFILENAME\" | rev | cut -d'.' -f2- | rev`"
fi

이중 확장에서만 작동하며 첫 번째 확장은 "tar"여야합니다.

그러나 문자열 길이 테스트로 "tar"테스트 라인을 변경하고 수정을 여러 번 반복 할 수 있습니다.

0
eadmaster