Bash의 경로 문자열에서 파일 접미사와 경로 부분을 어떻게 제거합니까?
과 같은 문자열 파일 경로가 주어지면 /foo/fizzbuzz.bar
bash를 사용하여 해당 fizzbuzz
문자열 의 일부만 추출하는 방법은 무엇입니까?
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)
두 가지 별도 작업으로 수행되는 순수 bash :
경로 문자열에서 경로를 제거하십시오.
path=/foo/bar/bim/baz/file.gif file=${path##*/} #$file is now 'file.gif'
경로 문자열에서 확장을 제거하십시오.
base=${file%.*} #${base} is now 'file'.
basename을 사용하여 이것을 달성하기 위해 다음을 사용했습니다.
for file in *; do
ext=${file##*.}
fname=`basename $file $ext`
# Do things with $fname
done;
파일 확장자에 대한 사전 지식이 필요하지 않으며 파일 이름에 점이있는 파일 이름 (확장자 앞)이있는 경우에도 작동합니다. 프로그램이 필요 basename
하지만 이것은 GNU coreutils의 일부이므로 배포판과 함께 제공되어야합니다.
순수한 배쉬 방법 :
~$ 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
perl -pe 's/\..*$//;s{^.*/}{}'
Using basename
는 파일 확장자가 무엇인지 알고 있다고 가정합니까?
그리고 다양한 정규식 제안이 하나 이상의 ""를 포함하는 파일 이름에 대처하지 못한다고 생각합니다.
다음은 이중 점에 대처하는 것 같습니다. 아, "/"자체를 포함하는 파일 이름 (킥만)
파스칼의 말을 인용하자면, "이 스크립트는 너무 깁니다. 더 짧게 만들 시간이 없었습니다."
#!/usr/bin/perl
$fullname = $ARGV[0];
($path,$name) = $fullname =~ /^(.*[^\\]\/)*(.*)$/;
($basename,$extension) = $name =~ /^(.*)(\.[^.]*)$/;
print $basename . "\n";
다른 게시물에서 제안한대로 기본 이름을 사용할 수없는 경우 언제든지 sed를 사용할 수 있습니다. 다음은 (못생긴) 예입니다. 가장 크지는 않지만 원하는 문자열을 추출하고 입력을 원하는 문자열로 대체하여 작동합니다.
echo '/foo/fizzbuzz.bar' | sed 's|.*\/\([^\.]*\)\(\..*\)$|\1|g'
어떤 결과를 얻을 수 있습니까?
피즈 버즈
또한받는 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
당신이 확장을 알고있는 경우에) 훨씬 더 간단합니다.
기본 이름으로 경로를 제거합니다. 제공된 접미사와 파일의 접미사와 일치하는 경우 접미사도 제거하지만 명령에 제공 할 접미사를 알아야합니다. 그렇지 않으면 mv를 사용하여 다른 이름이 무엇인지 알아낼 수 있습니다.
전체 경로없이 파일 이름을 얻으려면 최상위 답변과 두 번째 최상위 답변을 결합하십시오.
$ x="/foo/fizzbuzz.bar.quux"
$ y=(`basename ${x%%.*}`)
$ echo $y
fizzbuzz
'Programming' 카테고리의 다른 글
기존 Docker 컨테이너에 포트 매핑을 어떻게 할당합니까? (0) | 2020.02.28 |
---|---|
Android Studio에서 모듈을 삭제하는 방법 (0) | 2020.02.28 |
공개적으로 보이는 유형 또는 멤버에 대한 XML 주석이 누락되었습니다. (0) | 2020.02.28 |
우분투 12.04의 nodejs와 node (0) | 2020.02.28 |
MySQL의 여러 업데이트 (0) | 2020.02.28 |