스크립트에서 변수를 통해 찾기 명령의 경로 매개 변수에 ‘*’와일드 카드를 전달하는 방법은 무엇입니까? -print find te*/’my

find와일드 카드로 제한되지만 경로 이름에 공백이있는 폴더 세트에서 파일을 찾는 데 사용하고 싶습니다 .

커맨드 라인에서 이것은 쉽습니다. 다음 예제는 모두 작동합니다.

find  te*/my\ files/more   -print
find  te*/'my files'/more  -print
find  te*/my' 'files/more  -print

예를 들어 terminal/my files/more및 에서 파일을 찾습니다 tepid/my files/more.

그러나 나는 이것이 스크립트의 일부가되어야한다. 내가 필요한 것은 다음과 같습니다.

SEARCH='te*/my\ files/more'
find ${SEARCH} -print

불행히도 내가 무엇을하든 find스크립트 내의 명령에서 와일드 카드와 공백을 혼합 할 수없는 것 같습니다 . 위의 예는 다음과 같은 오류를 반환합니다 (예상치 않은 백 슬래시 배가).

find: te*/my\\’: No such file or directory
find: files/more’: No such file or directory

따옴표를 사용하려고하면 실패합니다.

SEARCH="te*/'my files'/more"
find ${SEARCH} -print

따옴표의 의미를 무시하고 다음 오류를 반환합니다.

find: te*/'my’: No such file or directory
find: ‘files'/more’: No such file or directory

여기 또 다른 예가 있습니다.

SEARCH='te*/my files/more'
find ${SEARCH} -print

예상대로 :

find: te*/my’: No such file or directory
find: files/more’: No such file or directory

내가 시도한 모든 변형은 오류를 반환합니다.

해결 방법이 있는데 너무 많은 폴더를 반환하기 때문에 잠재적으로 위험합니다. 모든 공백을 다음과 같이 물음표 (한 문자 와일드 카드)로 변환합니다.

SEARCH='te*/my files/more'
SEARCH=${SEARCH// /?}       # Convert every space to a question mark.
find ${SEARCH} -print

이것은 다음과 같습니다.

find te*/my?files/more -print

이것은 올바른 폴더뿐만 아니라을 반환 terse/myxfiles/more합니다.

내가하려는 일을 어떻게 달성 할 수 있습니까? 구글은 나를 도와주지 않았다 🙁



답변

동일한 명령이 스크립트에서 제대로 작동해야합니다.

#!/usr/bin/env bash
find  te*/my\ files/ -print

변수로 사용해야 하는 경우 조금 더 복잡해집니다.

#!/usr/bin/env bash
search='te*/my\ files/'
eval find "$search" -print

경고:

eval이와 같이 사용 하는 것은 안전하지 않으며 파일 이름에 특정 문자가 포함될 수있는 경우 임의적이고 유해한 코드가 실행될 수 있습니다. 자세한 내용은 bash FAQ 48 을 참조하십시오.

경로를 인수로 전달하는 것이 좋습니다.

#!/usr/bin/env bash
find "$@" -name "file*"

또 다른 접근법은 find완전히 피하고 bash의 확장 된 글러브 기능과 글로브를 사용하는 것입니다.

#!/usr/bin/env bash
shopt -s globstar
for file in te*/my\ files/**; do echo "$file"; done

globstarbash는 옵션을 사용할 수 있습니다 **재귀 적으로 일치 :

globstar
      If set, the pattern ** used in a pathname expansion con
      text will match all files and zero or  more  directories
      and  subdirectories.  If the pattern is followed by a /,
      only directories and subdirectories match.

도트 파일 (숨겨진 파일) 찾기 및 포함과 같이 100 % 작동하도록하려면

#!/usr/bin/env bash
shopt -s globstar
shopt -s dotglob
for file in te*/my\ files/**; do echo "$file"; done

echo루프없이 직접 사용할 수도 있습니다.

echo te*/my\ files/**


답변

배열은 어떻습니까?

$ tree Desktop/ Documents/
Desktop/
└── my folder
    └── more
        └── file
Documents/
└── my folder
    ├── folder
    └── more

5 directories, 1 file
$ SEARCH=(D*/my\ folder)
$ find "${SEARCH[@]}"
Desktop/my folder
Desktop/my folder/more
Desktop/my folder/more/file
Documents/my folder
Documents/my folder/more
Documents/my folder/folder

(*)와일드 카드와 일치하는 배열로 확장됩니다. 그리고 "${SEARCH[@]}"배열 ( [@]) 의 모든 요소로 확장되며 각각 개별적으로 인용됩니다.

뒤늦게, 나는 그 자체가 이것을 가능하게해야한다는 것을 깨달았다. 다음과 같은 것 :

find . -path 'D*/my folder/more/'


답변

마침내 답을 찾았습니다.

모든 공백에 백 슬래시를 추가하십시오.

SEARCH='te*/my files/more'
SEARCH=${SEARCH// /\\ }

이 시점에서 SEARCH포함 te*/my\ files/more합니다.

그런 다음을 사용하십시오 eval.

eval find ${SEARCH} -print

그렇게 간단합니다! 사용 eval${SEARCH}변수 의 해석을 무시합니다 .


답변