질문자 :ibz
파일 이름(확장자 없음)과 확장자를 별도로 얻고 싶습니다.
지금까지 찾은 최고의 솔루션은 다음과 같습니다.
NAME=`echo "$FILE" | cut -d'.' -f1` EXTENSION=`echo "$FILE" | cut -d'.' -f2`
파일 이름에 여러 개가 포함되어 있으면 작동하지 않기 때문에 잘못된 것 .
문자. abjs
가 있다고 가정해 보겠습니다. ab
및 js
대신 a
및 b.js
를 고려합니다.
다음을 사용하여 Python에서 쉽게 수행할 수 있습니다.
file, ext = os.path.splitext(path)
하지만 가능하다면 파이썬 인터프리터를 실행하지 않는 것이 좋습니다.
더 나은 아이디어가 있습니까?
먼저 경로 없이 파일 이름을 가져옵니다.
filename=$(basename -- "$fullfile") extension="${filename##*.}" filename="${filename%.*}"
또는 '.' 대신 경로의 마지막 '/'에 집중할 수 있습니다. 예측할 수 없는 파일 확장자가 있는 경우에도 작동해야 합니다.
filename="${fullfile##*/}"
문서를 확인할 수 있습니다.
Petesh~% FILE="example.tar.gz" ~% echo "${FILE%%.*}" example ~% echo "${FILE%.*}" example.tar ~% echo "${FILE#*.}" tar.gz ~% echo "${FILE##*.}" gz
자세한 내용은 Bash 매뉴얼의 쉘 매개변수 확장을 참조하십시오.
Juliano일반적으로 확장자를 이미 알고 있으므로 다음을 사용할 수 있습니다.
basename filename .extension
예를 들어:
basename /path/to/dir/filename.txt .txt
그리고 우리는 얻는다
filename
Tomi PoPOSIX 매개변수 확장의 마법을 사용할 수 있습니다.
bash-3.2$ FILENAME=somefile.tar.gz bash-3.2$ echo "${FILENAME%%.*}" somefile bash-3.2$ echo "${FILENAME%.*}" somefile.tar
파일 이름이 ./somefile.tar.gz
형식인 경우 echo ${FILENAME%%.*}
는 .
빈 문자열이 있을 것입니다.
(임시 변수를 사용하여 이 문제를 해결할 수 있습니다.
FULL_FILENAME=$FILENAME FILENAME=${FULL_FILENAME##*/} echo ${FILENAME%%.*}
)
이 사이트에서 더 자세히 설명합니다.
${variable%pattern} Trim the shortest match from the end ${variable##pattern} Trim the longest match from the beginning ${variable%%pattern} Trim the longest match from the end ${variable#pattern} Trim the shortest match from the beginning
sotapme파일에 확장자가 없거나 파일 이름이 없으면 작동하지 않는 것 같습니다. 다음은 내가 사용하는 것입니다. 내장 기능만 사용하고 더 많은(전부는 아니지만) 병리학적 파일 이름을 처리합니다.
#!/bin/bash for fullpath in "$@" do filename="${fullpath##*/}" # Strip longest match of */ from start dir="${fullpath:0:${#fullpath} - ${#filename}}" # Substring from 0 thru pos of filename base="${filename%.[^.]*}" # Strip shortest match of . plus at least one non-dot char from end ext="${filename:${#base} + 1}" # Substring from len of base thru end if [[ -z "$base" && -n "$ext" ]]; then # If we have an extension and no base, it's really the base base=".$ext" ext="" fi echo -e "$fullpath:\n\tdir = \"$dir\"\n\tbase = \"$base\"\n\text = \"$ext\"" done
다음은 몇 가지 테스트 사례입니다.
$ basename-and-extension.sh / /home/me/ /home/me/file /home/me/file.tar /home/me/file.tar.gz /home/me/.hidden /home/me/ .hidden.tar /home/me/... .
/:
디렉토리 = "/"
기본 = ""
내선 = ""
/집/나/:
디렉토리 = "/집/나/"
기본 = ""
내선 = ""
/홈/나/파일:
디렉토리 = "/집/나/"
기본 = "파일"
내선 = ""
/home/me/file.tar:
디렉토리 = "/집/나/"
기본 = "파일"
ext = "타르"
/home/me/file.tar.gz:
디렉토리 = "/집/나/"
기본 = "파일.tar"
내선 = "gz"
/home/me/.hidden:
디렉토리 = "/집/나/"
기본 = ".hidden"
내선 = ""
/home/me/.hidden.tar:
디렉토리 = "/집/나/"
기본 = ".hidden"
ext = "타르"
/집/나/..:
디렉토리 = "/집/나/"
기본 = ".."
내선 = ""
.:
디렉토리 = ""
기본 = "."
내선 = ""
Doctor Jpax> echo abjs | sed 's/\.[^.]*$//' ab pax> echo abjs | sed 's/^.*\.//' js
잘 작동하므로 다음을 사용할 수 있습니다.
pax> FILE=abjs pax> NAME=$(echo "$FILE" | sed 's/\.[^.]*$//') pax> EXTENSION=$(echo "$FILE" | sed 's/^.*\.//') pax> echo $NAME ab pax> echo $EXTENSION js
그런데 명령은 다음과 같이 작동합니다.
NAME
대한 명령은 "."
"."
가 아닌 임의의 숫자 뒤에 오는 문자 아무 것도 없이 줄 끝까지의 문자(즉, 마지막 "."
부터 줄 끝까지 포함하여 모든 것을 제거함). 이것은 기본적으로 정규식 속임수를 사용하는 욕심이 없는 대체입니다.
EXTENSION
대한 명령 "."
다음에 오는 임의의 수의 문자를 대체합니다. 아무 것도 없는 줄의 시작 부분에 있는 문자입니다(즉, 줄의 시작 부분에서 마지막 점까지 포함하여 모든 것을 제거합니다). 이것은 기본 작업인 욕심 많은 대체입니다.
paxdiablobasename
을 사용할 수 있습니다.
예시:
$ basename foo-bar.tar.gz .tar.gz foo-bar
제거할 확장자를 basename에 제공해야 하지만 항상 -z
와 함께 tar
.tar.gz
가 될 것임을 알 수 있습니다.
이것은 당신이 원하는 것을 해야 합니다:
tar -zxvf $1 cd $(basename $1 .tar.gz)
Bjarke Freund-HansenMellen은 블로그 게시물에 대한 댓글에서 다음과 같이 씁니다.
Bash를 사용하면 확장자 없이 파일 이름을 가져오는 ${file%.*}
와 확장자만 가져오는 ${file##*.}
그건,
file="thisfile.txt" echo "filename: ${file%.*}" echo "extension: ${file##*.}"
출력:
filename: thisfile extension: txt
Kebabbert이 간단한 작업을 위해 awk
, sed
또는 perl
사용할 필요가 없습니다. 매개변수 확장만 사용하는 순수 Bash, os.path.splitext()
참조 구현
os.path.splitext(path)
문서:
root + ext == path
및 ext 가 비어 있거나 마침표로 시작하고 최대 하나의 마침표를 포함하도록 경로 이름 경로를 쌍 (root, ext)
기본 이름의 선행 마침표는 무시됩니다. splitext('.cshrc')
('.cshrc', '')
반환합니다.
파이썬 코드:
root, ext = os.path.splitext(path)
배시 구현
선행 기간 존중
root="${path%.*}" ext="${path#"$root"}"
선행 마침표 무시
root="${path#.}";root="${path%"$root"}${root%.*}" ext="${path#"$root"}"
테스트
다음은 모든 입력에서 Python 참조 구현과 일치해야 하는 선행 마침표 무시 구현에 대한 테스트 사례입니다.
|---------------|-----------|-------| |path |root |ext | |---------------|-----------|-------| |' .txt' |' ' |'.txt' | |' .txt.txt' |' .txt' |'.txt' | |' txt' |' txt' |'' | |'*.txt.txt' |'*.txt' |'.txt' | |'.cshrc' |'.cshrc' |'' | |'.txt' |'.txt' |'' | |'?.txt.txt' |'?.txt' |'.txt' | |'\n.txt.txt' |'\n.txt' |'.txt' | |'\t.txt.txt' |'\t.txt' |'.txt' | |'a b.txt.txt' |'a b.txt' |'.txt' | |'a*b.txt.txt' |'a*b.txt' |'.txt' | |'a?b.txt.txt' |'a?b.txt' |'.txt' | |'a\nb.txt.txt' |'a\nb.txt' |'.txt' | |'a\tb.txt.txt' |'a\tb.txt' |'.txt' | |'txt' |'txt' |'' | |'txt.pdf' |'txt' |'.pdf' | |'txt.tar.gz' |'txt.tar' |'.gz' | |'txt.txt' |'txt' |'.txt' | |---------------|-----------|-------|
시험 결과
모든 테스트를 통과했습니다.
Cykercut
명령을 사용하여 마지막 두 확장자( ".tar.gz"
부분)를 제거할 수 있습니다.
$ echo "foo.tar.gz" | cut -d'.' --complement -f2- foo
의견에서 Clayton Hughes가 언급했듯이 질문의 실제 예에서는 작동하지 않습니다. 따라서 대안으로 다음과 같이 확장된 정규 표현식과 함께 sed
$ echo "mpc-1.0.1.tar.gz" | sed -r 's/\.[[:alnum:]]+\.[[:alnum:]]+$//' mpc-1.0.1
무조건 마지막 두 개(영숫자) 확장자를 제거하여 작동합니다.
[Anders Lindahl의 코멘트 후 다시 업데이트됨]
Some programmer dude허용 대답은 일반적인 경우에서 잘 작동하지만, 즉 에지의 경우, 실패 :
- 확장자가 없는 파일 이름(이 답변의 나머지 부분에서 접미사
extension=${filename##*.}
은 빈 문자열이 아닌 입력 파일 이름을 반환합니다. -
extension=${filename##*.}
은 이니셜을 포함하지 않습니다 .
, 관습에 어긋납니다.- 맹목적으로
.
접미사가 없는 파일 이름에서는 작동하지 않습니다.
-
filename="${filename%.*}"
은 입력 파일 이름이 로 시작하는 경우 빈 문자열이 됩니다 .
더 이상 포함하지 않습니다 .
문자(예: .bash_profile
) - 관례에 반합니다.
----------
따라서 모든 에지 케이스를 다루는 강력한 솔루션 의 복잡성은 함수를 호출합니다. 아래 정의를 참조하십시오. 경로의 모든 구성 요소를 반환할 수 있습니다 .
호출 예:
splitPath '/etc/bash.bashrc' dir fname fnameroot suffix # -> $dir == '/etc' # -> $fname == 'bash.bashrc' # -> $fnameroot == 'bash' # -> $suffix == '.bashrc'
입력 경로 뒤의 인수는 자유롭게 선택되며 위치 변수 이름 .
관심 있는 변수 앞에 오는 관심 없는 변수를 건너뛰려면 _
(폐기 변수 $_
) 또는 ''
. 예를 들어 파일 이름 루트와 확장자만 추출하려면 splitPath '/etc/bash.bashrc' _ _ fnameroot extension
.
# SYNOPSIS # splitPath path varDirname [varBasename [varBasenameRoot [varSuffix]]] # DESCRIPTION # Splits the specified input path into its components and returns them by assigning # them to variables with the specified *names*. # Specify '' or throw-away variable _ to skip earlier variables, if necessary. # The filename suffix, if any, always starts with '.' - only the *last* # '.'-prefixed token is reported as the suffix. # As with `dirname`, varDirname will report '.' (current dir) for input paths # that are mere filenames, and '/' for the root dir. # As with `dirname` and `basename`, a trailing '/' in the input path is ignored. # A '.' as the very first char. of a filename is NOT considered the beginning # of a filename suffix. # EXAMPLE # splitPath '/home/jdoe/readme.txt' parentpath fname fnameroot suffix # echo "$parentpath" # -> '/home/jdoe' # echo "$fname" # -> 'readme.txt' # echo "$fnameroot" # -> 'readme' # echo "$suffix" # -> '.txt' # --- # splitPath '/home/jdoe/readme.txt' _ _ fnameroot # echo "$fnameroot" # -> 'readme' splitPath() { local _sp_dirname= _sp_basename= _sp_basename_root= _sp_suffix= # simple argument validation (( $# >= 2 )) || { echo "$FUNCNAME: ERROR: Specify an input path and at least 1 output variable name." >&2; exit 2; } # extract dirname (parent path) and basename (filename) _sp_dirname=$(dirname "$1") _sp_basename=$(basename "$1") # determine suffix, if any _sp_suffix=$([[ $_sp_basename = *.* ]] && printf %s ".${_sp_basename##*.}" || printf '') # determine basename root (filemane w/o suffix) if [[ "$_sp_basename" == "$_sp_suffix" ]]; then # does filename start with '.'? _sp_basename_root=$_sp_basename _sp_suffix='' else # strip suffix from filename _sp_basename_root=${_sp_basename%$_sp_suffix} fi # assign to output vars. [[ -n $2 ]] && printf -v "$2" "$_sp_dirname" [[ -n $3 ]] && printf -v "$3" "$_sp_basename" [[ -n $4 ]] && printf -v "$4" "$_sp_basename_root" [[ -n $5 ]] && printf -v "$5" "$_sp_suffix" return 0 } test_paths=( '/etc/bash.bashrc' '/usr/bin/grep' '/Users/jdoe/.bash_profile' '/Library/Application Support/' 'readme.new.txt' ) for p in "${test_paths[@]}"; do echo ----- "$p" parentpath= fname= fnameroot= suffix= splitPath "$p" parentpath fname fnameroot suffix for n in parentpath fname fnameroot suffix; do echo "$n=${!n}" done done
기능을 실행하는 테스트 코드:
test_paths=( '/etc/bash.bashrc' '/usr/bin/grep' '/Users/jdoe/.bash_profile' '/Library/Application Support/' 'readme.new.txt' ) for p in "${test_paths[@]}"; do echo ----- "$p" parentpath= fname= fnameroot= suffix= splitPath "$p" parentpath fname fnameroot suffix for n in parentpath fname fnameroot suffix; do echo "$n=${!n}" done done
예상 출력 - 예외적인 경우에 유의하십시오.
- 접미사가 없는 파일 이름
- 파일 이름은로 시작
.
(접미사의 시작으로 간주 되지 않음) -
/
로 끝나는 입력 경로(후행 /
는 무시됨) - 파일 이름만 있는 입력 경로(
.
는 상위 경로로 반환됨) - 이상의 파일 이름
.
-접두사가 붙은 토큰(마지막만 접미사로 간주됨):
----- /etc/bash.bashrc parentpath=/etc fname=bash.bashrc fnameroot=bash suffix=.bashrc ----- /usr/bin/grep parentpath=/usr/bin fname=grep fnameroot=grep suffix= ----- /Users/jdoe/.bash_profile parentpath=/Users/jdoe fname=.bash_profile fnameroot=.bash_profile suffix= ----- /Library/Application Support/ parentpath=/Library fname=Application Support fnameroot=Application Support suffix= ----- readme.new.txt parentpath=. fname=readme.new.txt fnameroot=readme.new suffix=.txt
mklement0다음은 소프트웨어 패키지의 버전 번호 추출과 같은 일부 고급 사용 사례를 포함하여 몇 가지 대안 제안(대부분 awk
f='/path/to/complex/file.1.0.1.tar.gz' # Filename : 'file.1.0.x.tar.gz' echo "$f" | awk -F'/' '{print $NF}' # Extension (last): 'gz' echo "$f" | awk -F'[.]' '{print $NF}' # Extension (all) : '1.0.1.tar.gz' echo "$f" | awk '{sub(/[^.]*[.]/, "", $0)} 1' # Extension (last-2): 'tar.gz' echo "$f" | awk -F'[.]' '{print $(NF-1)"."$NF}' # Basename : 'file' echo "$f" | awk '{gsub(/.*[/]|[.].*/, "", $0)} 1' # Basename-extended : 'file.1.0.1.tar' echo "$f" | awk '{gsub(/.*[/]|[.]{1}[^.]+$/, "", $0)} 1' # Path : '/path/to/complex/' echo "$f" | awk '{match($0, /.*[/]/, a); print a[0]}' # or echo "$f" | grep -Eo '.*[/]' # Folder (containing the file) : 'complex' echo "$f" | awk -F'/' '{$1=""; print $(NF-1)}' # Version : '1.0.1' # Defined as 'number.number' or 'number.number.number' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' # Version - major : '1' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f1 # Version - minor : '0' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f2 # Version - patch : '1' echo "$f" | grep -Eo '[0-9]+[.]+[0-9]+[.]?[0-9]?' | cut -d. -f3 # All Components : "path to complex file 1 0 1 tar gz" echo "$f" | awk -F'[/.]' '{$1=""; print $0}' # Is absolute : True (exit-code : 0) # Return true if it is an absolute path (starting with '/' or '~/' echo "$f" | grep -q '^[/]\|^~/'
모든 사용 사례는 중간 결과에 의존하지 않고 원래의 전체 경로를 입력으로 사용합니다.
henfiber가장 작고 간단한 솔루션(한 줄)은 다음과 같습니다.
$ file=/blaabla/bla/blah/foo.txt echo $(basename ${file%.*}) # foo
Ron파일 이름만 필요한 경우 다음을 시도할 수 있다고 생각합니다.
FULLPATH=/usr/share/X11/xorg.conf.d/50-synaptics.conf # Remove all the prefix until the "/" character FILENAME=${FULLPATH##*/} # Remove all the prefix until the "." character FILEEXTENSION=${FILENAME##*.} # Remove a suffix, in our case, the filename. This will return the name of the directory that contains this file. BASEDIRECTORY=${FULLPATH%$FILENAME} echo "path = $FULLPATH" echo "file name = $FILENAME" echo "file extension = $FILEEXTENSION" echo "base directory = $BASEDIRECTORY"
그리고 그것이 모두 =D입니다.
Andrew Woolfgang필드 번호에 -
를 추가하여 모든 필드와 후속 필드를 표시하도록 강제로 잘라낼 수 있습니다.
NAME=`basename "$FILE"` EXTENSION=`echo "$NAME" | cut -d'.' -f2-`
따라서 FILE이 eth0.pcap.gz
이면 EXTENSION은 pcap.gz
동일한 논리를 사용하여 다음과 같이 cut과 함께 '-'를 사용하여 파일 이름을 가져올 수도 있습니다.
NAME=`basename "$FILE" | cut -d'.' -f-1`
이것은 확장자가 없는 파일 이름에 대해서도 작동합니다.
maciek gajewski매직 파일 인식
이 스택 오버플로 질문에 대한 많은 좋은 답변 외에도 다음을 추가하고 싶습니다.
Linux 및 기타 유닉스에는 file
첫 번째 바이트를 분석하여 파일 유형 감지를 수행하는 file 이라는 마법 명령이 있습니다. 이것은 초기에 인쇄 서버에 사용되는 아주 오래된 도구입니다(만들어지지 않은 경우... 잘 모르겠습니다).
file myfile.txt myfile.txt: UTF-8 Unicode text file -b --mime-type myfile.txt text/plain
/etc/mime.types
에서 찾을 수 있습니다(내 Debian GNU/Linux 데스크탑에서. man file
및 man mime.types
file
유틸리티와 mime-support
패키지를 설치해야 할 수도 있음):
grep $( file -b --mime-type myfile.txt ) </etc/mime.types text/plain asc txt text pot brf srt
올바른 확장을 결정하기 위해 bash 함수를 만들 수 있습니다. 약간의(완벽하지 않은) 샘플이 있습니다.
file2ext() { local _mimetype=$(file -Lb --mime-type "$1") _line _basemimetype case ${_mimetype##*[/.-]} in gzip | bzip2 | xz | z ) _mimetype=${_mimetype##*[/.-]} _mimetype=${_mimetype//ip} _basemimetype=$(file -zLb --mime-type "$1") ;; stream ) _mimetype=($(file -Lb "$1")) [ "${_mimetype[1]}" = "compressed" ] && _basemimetype=$(file -b --mime-type - < <( ${_mimetype,,} -d <"$1")) || _basemimetype=${_mimetype,,} _mimetype=${_mimetype,,} ;; executable ) _mimetype='' _basemimetype='' ;; dosexec ) _mimetype='' _basemimetype='exe' ;; shellscript ) _mimetype='' _basemimetype='sh' ;; * ) _basemimetype=$_mimetype _mimetype='' ;; esac while read -a _line ;do if [ "$_line" == "$_basemimetype" ] ;then [ "$_line[1]" ] && _basemimetype=${_line[1]} || _basemimetype=${_basemimetype##*[/.-]} break fi done </etc/mime.types case ${_basemimetype##*[/.-]} in executable ) _basemimetype='' ;; shellscript ) _basemimetype='sh' ;; dosexec ) _basemimetype='exe' ;; * ) ;; esac [ "$_mimetype" ] && [ "$_basemimetype" != "$_mimetype" ] && printf ${2+-v} $2 "%s.%s" ${_basemimetype##*[/.-]} ${_mimetype##*[/.-]} || printf ${2+-v} $2 "%s" ${_basemimetype##*[/.-]} }
이 함수는 나중에 사용할 수 있는 Bash 변수를 설정할 수 있습니다.
(이것은 @Petesh 정답에서 영감을 받았습니다):
filename=$(basename "$fullfile") filename="${filename%.*}" file2ext "$fullfile" extension echo "$fullfile -> $filename . $extension"
F. Hauri좋아, 내가 올바르게 이해했다면 여기서 문제는 여러 확장자를 가진 파일의 이름과 전체 확장자를 얻는 방법입니다(예: stuff.tar.gz
.
이것은 나를 위해 작동합니다.
fullfile="stuff.tar.gz" fileExt=${fullfile#*.} fileName=${fullfile%*.$fileExt}
이것은 파일 이름으로 stuff
.tar.gz
를 제공합니다. 0을 포함하여 모든 확장에서 작동합니다. 동일한 문제가 있는 사람에게 도움이 되길 바랍니다 =)
Al3xXx$ F = "text file.test.txt" $ echo ${F/*./} txt
이것은 파일 이름에 여러 개의 점과 공백을 제공하지만 확장자가 없으면 파일 이름 자체를 반환합니다. 그래도 확인하기 쉽습니다. 파일 이름과 확장자가 동일한지 테스트하십시오.
당연히 이 방법은 .tar.gz 파일에서는 작동하지 않습니다. 그러나 이는 2단계 프로세스로 처리될 수 있습니다. 확장자가 gz이면 tar 확장자가 있는지 다시 확인하십시오.
miriam나는 다음 스크립트를 사용한다
$ echo "foo.tar.gz"|rev|cut -d"." -f3-|rev foo
Joydip Datta${parameter%word}
사용하기만 하면 됩니다.
귀하의 경우:
${FILE%.*}
테스트하려면 다음 모든 작업이 수행되고 확장 프로그램을 제거하면 됩니다.
FILE=abc.xyz; echo ${FILE%.*}; FILE=123.abc.xyz; echo ${FILE%.*}; FILE=abc; echo ${FILE%.*};
enyo물고기 에서 파일 이름과 확장자를 추출하는 방법:
function split-filename-extension --description "Prints the filename and extension" for file in $argv if test -f $file set --local extension (echo $file | awk -F. '{print $NF}') set --local filename (basename $file .$extension) echo "$filename $extension" else echo "$file is not a valid file" end end end
주의 사항: 마지막 점에서 분할합니다. 점이 있는 파일 이름에는 잘 작동하지만 점이 있는 확장자에는 적합하지 않습니다. 아래 예를 참조하십시오.
용법:
$ split-filename-extension foo-0.4.2.zip bar.tar.gz foo-0.4.2 zip # Looks good! bar.tar gz # Careful, you probably want .tar.gz as the extension.
이 작업을 수행하는 더 좋은 방법이 있을 수 있습니다. 개선하기 위해 내 답변을 자유롭게 편집하십시오.
처리할 확장 기능이 제한되어 있고 모두 알고 있는 경우 다음을 시도하십시오.
switch $file case *.tar echo (basename $file .tar) tar case *.tar.bz2 echo (basename $file .tar.bz2) tar.bz2 case *.tar.gz echo (basename $file .tar.gz) tar.gz # and so on end
이 첫 번째 예로서주의를 가지고 있지 않지만, 당신이 기대할 수있는 얼마나 많은 확장에 따라 더 지루한 될 수 있도록 모든 경우를 처리 할 필요가 없습니다.
Dennis다음은 AWK 가 있는 코드입니다. 더 간단하게 할 수 있습니다. 하지만 저는 AWK를 잘 못합니다.
filename$ ls abc.a.txt abctxt pp-kk.txt filename$ find . -type f | awk -F/ '{print $2}' | rev | awk -F"." '{$1="";print}' | rev | awk 'gsub(" ",".") ,sub(".$", "")' abc.a abc pp-kk filename$ find . -type f | awk -F/ '{print $2}' | awk -F"." '{print $NF}' txt txt txt
smilyfacePetesh 답변에서 빌드하면 파일 이름만 필요한 경우 경로와 확장자를 한 줄로 제거할 수 있습니다.
filename=$(basename ${fullname%.*})
cvr크게 @ mklement0의 우수하고, 꽉 임의 유용 bashisms의의 기반으로 - 이것뿐만 아니라 다른 답변 / 기타 질문 / "이놈의 인터넷이 있음을"... 내가 조금의 모든 것을 싸서 조금 더 이해할 수있는, dirname
/ basename
/ what have you .. 의 보다 강력한 버전이어야 하는 것(내가 고려하는)을 처리하는 내(또는 귀하의) .bash_profile
대한 재사용 가능한 기능 ..
function path { SAVEIFS=$IFS; IFS="" # stash IFS for safe-keeping, etc. [[ $# != 2 ]] && echo "usage: path <path> <dir|name|fullname|ext>" && return # demand 2 arguments [[ $1 =~ ^(.*/)?(.+)?$ ]] && { # regex parse the path dir=${BASH_REMATCH[1]} file=${BASH_REMATCH[2]} ext=$([[ $file = *.* ]] && printf %s ${file##*.} || printf '') # edge cases for extensionless files and files like ".nesh_profile.coffee" [[ $file == $ext ]] && fnr=$file && ext='' || fnr=${file:0:$((${#file}-${#ext}))} case "$2" in dir) echo "${dir%/*}"; ;; name) echo "${fnr%.*}"; ;; fullname) echo "${fnr%.*}.$ext"; ;; ext) echo "$ext"; ;; esac } IFS=$SAVEIFS }
사용 예...
SOMEPATH=/path/to.some/.random\ file.gzip path $SOMEPATH dir # /path/to.some path $SOMEPATH name # .random file path $SOMEPATH ext # gzip path $SOMEPATH fullname # .random file.gzip path gobbledygook # usage: -bash <path> <dir|name|fullname|ext>
Alex Gray이것은 나를 위해 일한 유일한 것입니다.
path='folder/other_folder/file.js' base=${path##*/} echo ${base%.*} >> file
이것은 문자열 보간에서도 사용할 수 있지만 불행히도 base
을 설정해야 합니다.
Ken Mueller간단한 대답:
POSIX 변수 대답 을 확장하려면 더 흥미로운 패턴을 수행할 수 있습니다. 따라서 여기에 자세히 설명된 경우에는 다음과 같이 간단하게 수행할 수 있습니다.
tar -zxvf $1 cd ${1%.tar.*}
그러면 .tar의 마지막 항목이 잘립니다. <무언가> .
보다 일반적으로 의 마지막 항목을 제거하려는 경우 . <무언가> . <다른 것> 그럼
${1.*.*}
잘 작동해야합니다.
위의 답변 링크가 죽은 것 같습니다. 다음은 TLDP에서 Bash에서 직접 수행할 수 있는 많은 문자열 조작에 대한 훌륭한 설명입니다 .
RandyP빈 확장도 허용하려면 다음이 제가 생각해낼 수 있는 가장 짧은 것입니다.
echo 'hello.txt' | sed -r 's/.+\.(.+)|.*/\1/' # EXTENSION echo 'hello.txt' | sed -r 's/(.+)\..+|(.*)/\1\2/' # FILENAME
첫 번째 줄 설명: PATH.EXT 또는 ANYTHING과 일치하고 EXT로 바꿉니다. ANYTHING이 일치하면 ext 그룹이 캡처되지 않습니다.
phil294다음은 대소문자와 관련하여 이름이 충돌할 때 이름을 고유하게 만들기 위해 Bash 스크립트를 작성할 때 파일의 이름과 확장자를 찾는 데 사용한 알고리즘입니다.
#! /bin/bash # # Finds # -- name and extension pairs # -- null extension when there isn't an extension. # -- Finds name of a hidden file without an extension # declare -a fileNames=( '.Montreal' '.Rome.txt' 'Loundon.txt' 'Paris' 'San Diego.txt' 'San Francisco' ) echo "Script ${0} finding name and extension pairs." echo for theFileName in "${fileNames[@]}" do echo "theFileName=${theFileName}" # Get the proposed name by chopping off the extension name="${theFileName%.*}" # get extension. Set to null when there isn't an extension # Thanks to mklement0 in a comment above. extension=$([[ "$theFileName" == *.* ]] && echo ".${theFileName##*.}" || echo '') # a hidden file without extenson? if [ "${theFileName}" = "${extension}" ] ; then # hidden file without extension. Fixup. name=${theFileName} extension="" fi echo " name=${name}" echo " extension=${extension}" done
테스트 실행.
$ config/Name\&Extension.bash Script config/Name&Extension.bash finding name and extension pairs. theFileName=.Montreal name=.Montreal extension= theFileName=.Rome.txt name=.Rome extension=.txt theFileName=Loundon.txt name=Loundon extension=.txt theFileName=Paris name=Paris extension= theFileName=San Diego.txt name=San Diego extension=.txt theFileName=San Francisco name=San Francisco extension= $
참고: 완전한 음역 프로그램과 더 많은 테스트 사례는 https://www.dropbox.com/s/4c6m0f2e28a1vxf/avoid-clashes-code.zip?dl=0에서 찾을 수 있습니다.
historystamp/Users/Jonathan/Scripts/bash/MyScript.sh
예제 파일을 사용하여 이 코드는 다음과 같습니다.
MY_EXT=".${0##*.}" ME=$(/usr/bin/basename "${0}" "${MY_EXT}")
${ME}
는 MyScript
이고 ${MY_EXT}
는 .sh
.
스크립트:
#!/bin/bash set -e MY_EXT=".${0##*.}" ME=$(/usr/bin/basename "${0}" "${MY_EXT}") echo "${ME} - ${MY_EXT}"
일부 테스트:
$ ./MyScript.sh MyScript - .sh $ bash MyScript.sh MyScript - .sh $ /Users/Jonathan/Scripts/bash/MyScript.sh MyScript - .sh $ bash /Users/Jonathan/Scripts/bash/MyScript.sh MyScript - .sh
chown위의 답변에서 Python을 모방하는 가장 짧은 oneliner
file, ext = os.path.splitext(path)
파일에 실제로 확장자가 있다고 가정하면
EXT="${PATH##*.}"; FILE=$(basename "$PATH" .$EXT)
commonpike출처 : http:www.stackoverflow.com/questions/965053/extract-filename-and-extension-in-bash