programing

bash에 경로 및 확장자가 없는 파일 기본 이름 추출

oldcodes 2023. 4. 29. 09:52
반응형

bash에 경로 및 확장자가 없는 파일 기본 이름 추출

다음과 같은 파일 이름이 지정됩니다.

/the/path/foo.txt
bar.txt

다음을 얻을 수 있기를 바랍니다.

foo
bar

왜 안 되는 거지?

#!/bin/bash

fullfile=$1
fname=$(basename $fullfile)
fbname=${fname%.*}
echo $fbname

그것을 하는 올바른 방법은 무엇입니까?

외부에 전화할 필요가 없습니다.basename지휘권대신 다음 명령을 사용할 수 있습니다.

$ s=/the/path/foo.txt
$ echo "${s##*/}"
foo.txt
$ s=${s##*/}
$ echo "${s%.txt}"
foo
$ echo "${s%.*}"
foo

이 솔루션은 모든 최신(2004년 이후) POSIX 호환 셸에서 작동해야 합니다(예:bash,dash,ksh등).

소스: 셸 명령어 2.6.2 매개 변수 확장

bash 문자열 조작에 대한 더 많은 정보: http://tldp.org/LDP/LG/issue18/bash.html

기본 이름 명령에는 두 가지 다른 호출이 있습니다. 하나는 경로만 지정하여 마지막 구성 요소를 제공하고 다른 하나는 제거할 접미사를 제공합니다.따라서 기본 이름의 두 번째 호출을 사용하여 예제 코드를 단순화할 수 있습니다.또한 다음 사항을 올바르게 인용하도록 주의하십시오.

fbname=$(기본 이름 "$1" .txt)echo "$fbname"

기본 이름과 컷의 조합은 다음과 같이 이중으로 끝나는 경우에도 잘 작동합니다..tar.gz:

fbname=$(basename "$fullfile" | cut -d. -f1)

이 솔루션이 Bash Parameter Expansion보다 산술 능력이 덜 필요하다면 흥미로울 것입니다.

다음은 하나의 한정자입니다.

  1. $(basename "${s%.*}")
  2. $(basename "${s}" ".${s##*.}")

저는 이것이 필요했는데, 봉방이와 우리가 트윗을 했던 것과 같습니다.

순수하다bash,아니요.basename변수 저글링 없음.문자열을 설정하고echo:

p=/the/path/foo.txt
echo "${p//+(*\/|.*)}"

출력:

foo

참고: 더bash extglobal 옵션은 "on"이어야 합니다(Ubuntu는 extglobal을 기본적으로 "on"으로 설정). 그렇지 않으면 다음을 수행합니다.

shopt -s extglob

를 통해 걷기${p//+(*\/|.*)}:

  1. ${p$p부터 시작합니다.
  2. //이어지는 패턴의 모든 인스턴스를 대체합니다.
  3. +(괄호 안의 패턴 목록 중 하나 이상과 일치합니다(즉, 아래 항목 #7까지).
  4. 번째 패턴:*\/리터럴 " 앞에 있는 것과 일치합니다./챠의
  5. 패턴 구분 기호| 경우 논리적 OR과 같은 역할을 합니다.
  6. 번째 패턴:.*리터럴 " 뒤에 있는 모든 것과 일치합니다..-- 즉, 에서bash그". 마침표 문자일 뿐 정규식 점이 아닙니다.
  7. )종료 패턴 목록.
  8. }매개 변수 확장을 종료합니다.문자열 대체를 사용하면 일반적으로 다른 문자열이 있습니다./다음에 대체 문자열이 나옵니다.하지만 없기 때문에./여기서 일치하는 패턴은 아무것도 아닌 것으로 대체됩니다. 이렇게 하면 일치하는 패턴이 삭제됩니다.

man bash배경:

  1. 패턴 대체:
  ${parameter/pattern/string}
          Pattern substitution.  The pattern is expanded to produce a pat
          tern just as in pathname expansion.  Parameter is  expanded  and
          the  longest match of pattern against its value is replaced with
          string.  If pattern begins with /, all matches  of  pattern  are
          replaced   with  string.   Normally  only  the  first  match  is
          replaced.  If pattern begins with #, it must match at the begin‐
          ning of the expanded value of parameter.  If pattern begins with
          %, it must match at the end of the expanded value of  parameter.
          If string is null, matches of pattern are deleted and the / fol
          lowing pattern may be omitted.  If parameter is @ or *, the sub
          stitution  operation  is applied to each positional parameter in
          turn, and the expansion is the resultant list.  If parameter  is
          an  array  variable  subscripted  with  @ or *, the substitution
          operation is applied to each member of the array  in  turn,  and
          the expansion is the resultant list.
  1. 확장 패턴 일치:
  If the extglob shell option is enabled using the shopt builtin, several
   extended  pattern  matching operators are recognized.  In the following
   description, a pattern-list is a list of one or more patterns separated
   by a |.  Composite patterns may be formed using one or more of the fol
   lowing sub-patterns:

          ?(pattern-list)
                 Matches zero or one occurrence of the given patterns
          *(pattern-list)
                 Matches zero or more occurrences of the given patterns
          +(pattern-list)
                 Matches one or more occurrences of the given patterns
          @(pattern-list)
                 Matches one of the given patterns
          !(pattern-list)
                 Matches anything except one of the given patterns

또 다른 더 복잡한). " 파이름나더확가를또져다다는있오방니습른법이장복자한일잡이더▁the"를 사용하십시오. 먼저rev 경로를 로, 첫 파일경는명령하, 서잘라냄에번째에서 입니다..다음과 같이 파일 경로를 다시 반전합니다.

filename=`rev <<< "$1" | cut -d"." -f2- | rev`
fileext=`rev <<< "$1" | cut -d"." -f1 | rev`

Windows 파일 경로(Cygwin 아래)를 잘 사용하려면 다음을 시도할 수도 있습니다.

fname=${fullfile##*[/|\\]}

이는 Windows에서 BasSH를 사용할 때 백슬래시 구분 기호를 고려합니다.

확장을 추출하기 위해 생각해 낸 대안입니다. 이 스레드의 게시물을 저에게 더 친숙한 저만의 작은 지식 기반으로 사용합니다.

ext="$(rev <<< "$(cut -f "1" -d "." <<< "$(rev <<< "file.docx")")")"

참고: 인용문을 사용하는 방법에 대해 조언해 주십시오. 제게는 효과가 있었지만 적절한 사용법에 대해 뭔가를 놓치고 있을 수 있습니다(아마 너무 많이 사용할 것입니다).

basname 명령을 사용합니다. 웹 페이지는 다음과 같습니다. http://unixhelp.ed.ac.uk/CGI/man-cgi?basename

언급URL : https://stackoverflow.com/questions/2664740/extract-file-basename-without-path-and-extension-in-bash

반응형