부분적으로 알려진 디렉터리에서 하위 디렉터리 경로 추출

부분적으로 알려진 디렉터리에서 하위 디렉터리 경로 추출

다음과 같은 디렉터리 구조가 있다고 가정해 보겠습니다.

base/
|
+-- app
|   |
|   +-- main
|       |
|       +-- sub
|           |
|           +-- first
|           |   |
|           |   +-- tib1.ear
|           |   \-- tib1.xml
|           |
|           \-- second
|               |
|               +-- tib2.ear
|               \-- tib2.xml

파일의 상대 경로 중 하나 ear는 입니다 base/app/main/sub/first/tib1.ear. 다음 하위 문자열을 추출하려면 어떻게 해야 합니까?

  • 파일 tib1.ear또는tib2.ear
  • 파일 뒤의 하위 디렉터리(파일 제외) base/app/, 즉 main/sub/first또는main/sub/second

모든 디렉토리 이름은 동적으로 생성되므로 알 수 없으므로 base/app/단순히 알려진 하위 문자열의 길이를 가져와서 cut잘라낼 수는 없지만 파일 이름이 알려지면 이것이 어떻게 가능한지 알고 있습니다. 다른 결과의 길이에 따라 여러 문자열을 자르고 연결하는 것보다 더 쉬운 방법이 있다고 생각합니다.

이와 비슷한 정규식 마술을 본 기억이 납니다. 여기에는 백슬래시를 사용하여 하위 문자열을 분할하고 연결하는 작업이 포함되지만 불행히도 어떻게 수행했는지 또는 어디서 보고 다시 찾았는지 기억이 나지 않습니다.

답변1

파일 이름부터 시작해 보겠습니다.

$ f=base/app/main/sub/first/tib1.ear

기본 이름을 추출하려면:

$ echo "${f##*/}"
tib1.ear

디렉토리 이름의 필수 부분을 추출하려면 다음을 수행하십시오.

$ g=${f%/*}; echo "${g#base/app/}"
main/sub/first

${g#base/app/}그리고 ${f##*/}예이다접두사 제거. ${f%/*}예이다접미사 제거.

문서

에서 man bash:

   ${parameter#word}
   ${parameter##word}
          Remove  matching prefix pattern.  The word is expanded to produce a pattern just as in pathname expansion.  If
          the pattern matches the beginning of the value of parameter, then the result of the expansion is the  expanded
          value  of  parameter  with the shortest matching pattern (the ``#'' case) or the longest matching pattern (the
          ``##'' case) deleted.  If parameter is @ or *, the pattern removal 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 pattern removal operation is applied to each member of the array in turn, and  the  expansion
          is the resultant list.

   ${parameter%word}
   ${parameter%%word}
          Remove  matching suffix pattern.  The word is expanded to produce a pattern just as in pathname expansion.  If
          the pattern matches a trailing portion of the expanded value of parameter, then the result of the expansion is
          the  expanded  value  of parameter with the shortest matching pattern (the ``%'' case) or the longest matching
          pattern (the ``%%'' case) deleted.  If parameter is @ or *, the pattern removal operation is applied  to  each
          positional parameter in turn, and the expansion is the resultant list.  If parameter is an array variable sub‐
          scripted with @ or *, the pattern removal operation is applied to each member of the array in  turn,  and  the
          expansion is the resultant list.

대안

basename유틸리티 와 다음을 고려할 수도 있습니다 dirname.

$ basename "$f"
tib1.ear
$ dirname "$f"
base/app/main/sub/first

답변2

테스트 파일 생성

mkdir -p base/app/main/sub/{first,second}
touch base/app/main/sub/first/tib1.{ear,xml}
touch base/app/main/sub/second/tib2.{ear,xml}

Bash를 사용하여 Ear 파일 찾기

shopt -s globstar nullglob
ear_files=( base/**/*.ear )
printf "%s\n" "${ear_files[@]}"
base/app/main/sub/first/tib1.ear
base/app/main/sub/second/tib2.ear

배열을 반복하고 John1024의 답변을 사용하여 각 경로에서 필요한 정보를 추출합니다.

for f in "${ear_files[@]}"; do ...; done

관련 정보