답변:
Bash의 # 및 % 연산자로 수행하는 방법은 다음과 같습니다.
$ x="/foo/fizzbuzz.bar"
$ y=${x%.bar}
$ echo ${y##*/}
fizzbuzz
${x%.bar}
${x%.*}
점 ${x%%.*}
뒤의 모든 것을 제거 하거나 첫 번째 점 뒤의 모든 것을 제거 하는 것일 수도 있습니다 .
예:
$ x="/foo/fizzbuzz.bar.quux"
$ y=${x%.*}
$ echo $y
/foo/fizzbuzz.bar
$ y=${x%%.*}
$ echo $y
/foo/fizzbuzz
설명서는 Bash 매뉴얼 에서 찾을 수 있습니다 . 찾으 ${parameter%word}
과 ${parameter%%word}
부 정합 부 후단.
basename 명령을보십시오 :
NAME="$(basename /foo/fizzbuzz.bar .bar)"
basename을 사용하여 이것을 달성하기 위해 다음을 사용했습니다.
for file in *; do
ext=${file##*.}
fname=`basename $file $ext`
# Do things with $fname
done;
파일 확장자에 대한 사전 지식이 필요하지 않으며 파일 이름에 점이있는 파일 이름이있는 경우에도 작동합니다 (확장자 앞). 프로그램이 필요 basename
하지만 이것은 GNU coreutils의 일부이므로 배포판과 함께 제공되어야합니다.
fname=`basename $file .$ext`
순수한 배쉬 방법 :
~$ x="/foo/bar/fizzbuzz.bar.quux.zoom";
~$ y=${x/\/*\//};
~$ echo ${y/.*/};
fizzbuzz
이 기능은 man bash에서 "Parameter Expansion"에 설명되어 있습니다. 비 배쉬 방법은 풍부합니다 : awk, perl, sed 등.
편집 : 파일 접미사의 점으로 작동 하며 접미사 (확장자)를 알 필요 는 없지만 이름 자체의 점으로는 작동 하지 않습니다 .
basename 및 dirname 함수는 다음과 같습니다.
mystring=/foo/fizzbuzz.bar
echo basename: $(basename "${mystring}")
echo basename + remove .bar: $(basename "${mystring}" .bar)
echo dirname: $(dirname "${mystring}")
출력 :
basename: fizzbuzz.bar
basename + remove .bar: fizzbuzz
dirname: /foo
mystring=$1
(여러 경고를 억제하고 공백 / 글로브 문자 등을 포함하지 않아야 함) 문제를 해결할 수 있습니다 발견?
echo "basename: $(basename "$mystring")"
- 완료 후 현재 디렉토리의 파일 목록으로 바꾸지 mystring='/foo/*'
않으면 그렇게하십시오 . *
basename
Using basename
는 파일 확장자가 무엇인지 알고 있다고 가정합니까?
그리고 다양한 정규식 제안이 하나 이상의 ""를 포함하는 파일 이름을 처리하지 못한다고 생각합니다.
다음은 이중 점에 대처하는 것 같습니다. 아, "/"자체를 포함하는 파일 이름 (킥만)
파스칼의 말을 인용하자면 "죄송합니다.이 스크립트는 너무 길어요.
#!/usr/bin/perl
$fullname = $ARGV[0];
($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
print $basename . "\n";
또한받는 POSIX 준수 구문 에서 사용 이 응답 ,
basename string [suffix]
에서와 같이
basename /foo/fizzbuzz.bar .bar
GNUbasename
는 다른 구문을 지원합니다.
basename -s .bar /foo/fizzbuzz.bar
같은 결과로. 차이점과 장점은 여러 인수를 지원 하는 -s
implies입니다 -a
.
$ basename -s .bar /foo/fizzbuzz.bar /baz/foobar.bar
fizzbuzz
foobar
이 -z
옵션 은 옵션을 사용하여 출력을 NUL 바이트로 분리하여 파일 이름을 안전하게 만들 수도 있습니다 ls
.
$ ls has*
'has'$'\n''newline.bar' 'has space.bar' 'has*.bar'
배열로 읽기 :
$ readarray -d $'\0' arr < <(basename -zs .bar has*)
$ declare -p arr
declare -a arr=([0]=$'has\nnewline' [1]="has space" [2]="has*")
readarray -d
Bash 4.4 이상이 필요합니다. 이전 버전의 경우 다음을 반복해야합니다.
while IFS= read -r -d '' fname; do arr+=("$fname"); done < <(basename -zs .bar has*)
제안 된 펄 솔루션에주의하십시오 : 첫 번째 점 뒤의 모든 것을 제거합니다.
$ echo some.file.with.dots | perl -pe 's/\..*$//;s{^.*/}{}'
some
펄로하고 싶다면 다음과 같이하십시오.
$ echo some.file.with.dots | perl -pe 's/(.*)\..*$/$1/;s{^.*/}{}'
some.file.with
하지만 당신은 강타와 솔루션을 사용하는 경우 y=${x%.*}
(또는 basename "$x" .ext
당신이 확장을 알고있는 경우에) 훨씬 더 간단합니다.
전체 경로없이 파일 이름을 얻으려면 최상위 답변과 두 번째 최상위 답변을 결합하십시오.
$ x="/foo/fizzbuzz.bar.quux"
$ y=(`basename ${x%%.*}`)
$ echo $y
fizzbuzz
${parameter%word}
과${parameter%%word}
부분 일치하는 부분을 후행한다.