파일 경로를 저장하는 목록(예: ( ))이 있습니다 impl/src/main/java/org/jboss/weld/util/collections/multimaps.java
. 경로는 저장되기 전에 소문자로 변환됩니다.
이제 bash 스크립트에서 이 파일에 액세스해야 합니다. 쉘을 "복구"하고 파일을 찾는 간단한 명령이 있습니까? 단순화를 위해 파일이 조건이 다른 여러 버전으로 존재하지 않는다고 가정합니다. 또한 경로에 있는 디렉터리의 대소문자를 수정해야 할 수도 있습니다.
find 사용을 고려했지만 전체 경로를 가질 수 없으므로 find . -iname multimaps.java
루트에서 여러 파일이 반환될 수 있으며 그 중 하나만 올바른 디렉터리 구조에 있습니다.
Bash 스크립트의 변수로 끝나려면 올바른 경로가 필요합니다.
답변1
GNU에는 내 문제를 해결하는 조건자가 find
있습니다 .-iwholename
find . -iwholename ./impl/src/main/java/org/jboss/weld/util/collections/multimaps.java
변수에 넣으려면 다음을 수행하십시오.
cased=`find . -iwholename "$filepath"`
답변2
그리고 zsh
:
setopt extendedglob
files=((#i)${(f)^"$(<file.list)"}(N))
printf '%s\n' $files
( file.list
한 줄에 하나씩 소문자 경로 목록이 포함된 파일).
(#i)
: 대소문자를 구분하지 않는 glob(필수extendedglob
)${(f)"$expansion"}
: 개행(개행) 시 분할 확장${^array}
: 버팀대 확장형으로 배열을 확장합니다.(N)
: nullglob glob 한정자(일치하지 않는 glob 제거).
단일 파일의 경우 다음과 같습니다.
setopt extendedglob
file=impl/src/main/java/org/jboss/weld/util/collections/multimaps.java
matches=((#i)$file)
(여기에서는 생략되었으므로 (N)
일치하는 항목이 없으면 오류가 발생합니다)
이에 상응하는 ksh93
것은 다음과 같습니다.
matches=(~(iN)"$file") # N for nullglob, otherwise the glob expands to itself
# instead of giving an error when it doesn't match.
bash
대소문자를 구분하지 않는 옵션이 있습니다 nocaseglob
. 하지만
일치=($파일)
불가능한. 당신은해야합니다~할 수 있게 하다다음과 같이 와일드카드 연산자를 사용하여 각 경로 구성 요소를 와일드카드로 카드 처리합니다.
shopt -s nocaseglob nullglob
matches=([i]mpl/[s]rc/[m]ain/[j]ava/[o]rg/[j]boss/[w]eld/[u]til/[c]ollections/[m]ultimaps.java)
[...]
glob 연산자를 지원하는 모든 쉘의 경우 (따라서 본질적으로 제외) glob as 등을 fish
다시 작성할 수도 있습니다 .[iI][mM][pP][lL]/[sS][rR]...
와 달리 find . -ipath "./$file"
쉘은 전체 디렉토리 트리를 크롤링할 필요가 없습니다. 먼저 현재 디렉터리를 읽어 or 또는 etc find
라고 불리는 디렉터리(또는 디렉터리에 대한 심볼릭 링크! 또 다른 차이점) 를 찾은 다음 해당 디렉터리의 내용을 읽어서 // 등 을 찾습니다.impl
Impl
ImPl
src
SRC
srC
또 다른 차이점은 경로 구성 요소에 전역 연산자(예 impl/***src***/whatever
: )가 포함되어 있어도 여전히 잘 작동한다는 것입니다.
답변3
배쉬에서:
shopt -s nocasematch globstar
for f in **; do for search in "${files[*]}"; do [[ $f == $search ]] && echo Found "$search" at: "$f"; done; done
nocasematch 쉘 옵션은 [[ ... == ... ]]
문자열을 비교할 때 대소문자를 무시하도록 명령에 지시합니다. globstar 쉘은 **
무차별 대입 bash 에뮬레이션을 수행할 수 있습니다. 이는 도트 파일을 건너뛰고( 설정되지 않은 경우) 심볼릭 링크를 따른다는 점에서 find
다릅니다 .find
shopt -s dotglob
답변4
각 파일에 대해 트리를 반복해서 스캔하는 것을 피하는 방법은 디렉토리 트리를 한 번 나열한 다음 해시 테이블에서 경로의 소문자 번역을 찾는 것입니다. 예를 들어:
NL='
'
find . -name "*$NL*" -prune -o -print | awk '
!list_processed {paths["./" $0]; next}
tolower($0) in paths' file.list list_processed=1 -
( file.list
한 줄에 하나씩 소문자로 된 파일 목록이 포함되어 있습니다).
file.list
목록이 줄바꿈으로 구분된 경우 목록에 저장될 가능성이 낮고 후처리가 중단되므로 이름에 줄바꿈이 있는 파일은 디렉터리로 이동하는 대신 건너뜁니다 .
그러나 파일 이름에 잘못된 문자가 포함되어 있으면 건너뛰기가 작동하지 않습니다. 보다바이트 및 문자부분적으로 위치함찾기 결과를 반복하는 것이 왜 나쁜 습관입니까?자세한 내용은.