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
그런 다음 .gz
앞에 .tar
문자열이 있는지 확인해야합니다. 그렇다면 확장 프로그램은 .tar.gz
.
댓글
- file = " /dir/subdir/file-1.0.tar.bz2
; echo $ {file ## *.}는 여기에 ' .bz2 '를 인쇄합니다. ' 예상되는 출력은 무엇입니까?
.tar.bz2
답변
파일 이름이 file-1.0.tar.bz2
인 경우 확장자는 bz2
입니다. 확장 프로그램을 추출하는 데 사용하는 방법 (fileext=${filename##*.}
)은 완벽하게 유효합니다 ¹.
확장 프로그램이 iv id =가되도록 어떻게 결정합니까? bz2
또는 0.tar.bz2
가 아닌 “e35c7cbf75″>
입니까? 먼저이 질문에 답해야합니다. 그런 다음 무엇을 파악할 수 있습니다. 쉘 명령이 사양과 일치합니다.
-
가능한 사양 중 하나는 확장이 문자로 시작해야한다는 것입니다.이 휴리스틱은
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 = ?*.@(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 스타일 쉘에서 작동합니다.
댓글
- 마지막
.
토큰 앞의 문자열이 아카이브 유형인지 확인하여 해결해야합니다 (예 :tar
).반복이 종료되어야합니다.
- @uray :이 특정 경우에 작동하지만 일반적인 솔루션은 아닙니다 ' . Maciej '의
.patch.lzma
의 예를 고려해보세요. istic은 마지막.
뒤 문자열을 고려하는 것입니다. ' 압축 접미사 (.7z
,.bz2
,.gz
, …), 계속 제거합니다. - @NoamM 들여 쓰기에 무엇이 잘못 되었나요? 수정 후에는 ' 확실히 깨졌습니다. 이중 중첩 코드는 단일 중첩 코드와 동일하게 들여 쓰기됩니다.
답변
확장자를 두 번 추출하는 대신 파일 이름에 패턴 일치를 수행하여 문제를 단순화 할 수 있습니다.
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
댓글
- 이 솔루션은 매우 간단합니다.
답변
$ echo "thisfile.txt"|awk -F . "{print $NF}"
여기에 댓글 : http://liquidat.wordpress.com/2007/09/29/short-tip-get-file-extension-in-shell-script/
댓글
-
.tar.gz
확장자에서 작동하지 않음 - 음 .tar .gz는 실제로 gzip 파일 내부의 tar이므로 gzip 파일에서 gz 확장자를 제거한다는 의미에서 작동합니다.
답변
여기에 내 장면이 있습니다. 점을 줄 바꿈으로 변환하고 tail
, 마지막 줄 가져 오기 :
$> TEXT=123.234.345.456.456.567.678 $> echo $TEXT | tr . \\n | tail -n1 678
답변
언젠가 저는 그 까다로운 기능을 만들었습니다.
# 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 이러한 기능이 마음에 들었거나 충분히 사용되었다고 생각한다면, 이 게시물을 참조하십시오 🙂 (그리고 코멘트를 남겨주세요).
답변
echo ${filename#$(echo $filename | sed "s/\.[^[:digit:]].*$//g;")}
예 :
댓글
- 일부 경우에 작동하지 않습니다. ' foo.7z '
- 따옴표가 필요하며 파일 이름에 백 슬래시가 포함되어 있거나
-
로 시작하는 경우 :"${filename#$(printf %s "$filename" | sed 's/\.[^[:digit:]].*$//g;')}"
- @axel_c : 맞습니다. 저는 ' Maciej와 동일한 사양을 예로 구현했습니다. '가 “문자로 시작”보다 더 나은 경험적 방법은 무엇입니까?
- @Gilles : 그게 있다고 생각합니다 '는 해결책이 아닙니다.
답변
잭맨 사례 기반 답변은 매우 훌륭하고 이식 가능하지만 변수에 파일 이름과 확장자 만 원하는 경우이 솔루션을 찾았습니다.
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”테스트 행을 변경하고 수정을 여러 번 반복 할 수 있습니다. .
답변
다음을 사용하여 해결했습니다.
filename=`basename $filepath` fileext=${filename##*.} fileext2=${filename%.*} fileext3=${fileext2##*.} if [ "$fileext3" == "tar" ]; then fileext="tar."$fileext fi
그러나 이것은 알려진 보관 유형에서만 작동합니다.이 경우에는 tar