다음과 같은 디렉터리 구조가 있다고 가정해 보겠습니다.
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