쉘 스크립트, find -name 및 와일드카드 확장

쉘 스크립트, find -name 및 와일드카드 확장

find -namesh내 스크립트에서 사용 하려고합니다.이전에 계산된조건에 대한 복잡한 인수. 단순화하면 다음과 같습니다

cond="-name '*.txt*"
find . $cond -ls

하지만 이제 내가 겪고 있는 문제는 의 와일드카드가 호출 $cond되기 전에 셸에 의해 확장 되거나 find.find

이를 테스트하기 위해 빈 테스트 디렉터리에서 다음을 수행했습니다.

touch a.txt b.txt c.dat

그런 다음 반복

cond="-name '*.txt'"; echo $cond; find . $cond

$cond내가 생각할 수 있는 모든 종류의 인용/이스케이프를 사용하여 다른 값을 사용합니다.

.네 개의 항목( 디렉토리 포함) 을 모두 얻었지만 파일은 없거나 알 수 없는 기본 또는 운영자 find라는 메시지가 표시됩니다 . b.txt물론 올바른 출력은 두 개의 텍스트 파일이어야 합니다.

어떤 팁이 있나요? 나는 기본적인 것을 놓치고 있다고 확신합니다.

답변1

Bourne과 유사한 쉘( 제외 zsh)에서 목록 컨텍스트에서 인용되지 않은 변수 확장을 유지하는 것은 다음과 같습니다.분할+전역운영자. 존재하다:

cond="-name '*.txt'"; echo $cond

의 내용은 $cond먼저 $IFS특수 변수의 값을 기준으로 분할됩니다. 기본적으로 ASCII 공백, 탭 및 개행 문자입니다.

그래서 그건나뉘다을 입력 -name하고 '*.txt'. 그 다음에전반적인 상황부분적으로 적용됩니다. 모든성격와일드카드 문자가 포함된 경우( *여기서 두 번째 문자), 단어는 패턴과 일치하는 파일 목록으로 확장되거나, 일치하는 파일이 없으면 변경되지 않고 그대로 유지됩니다. 따라서 일치하는 파일이 없으면 현재 디렉터리에서 이름이 로 끝나거나 확장되는 파일 목록이 확장됩니다 '*.txt'.'.txt''*.txt'

이 단어 목록은 별도의 인수로 에 전달됩니다 echo. 일치하는 파일이 없으면 , 및 3 echo개의 인수가 수신됩니다 ."echo""-name""'*.txt'"

물론 find명령에도 동일하게 적용됩니다.

명령이 매개변수 sum 을 find받기를 원하므로 조정해야 합니다.-name*.txt분할+전역운영자.

$IFS에서 사용하는 구분 기호와 일치하는 값이 필요합니다 $cond. 예를 들어:

cond='-name:*.txt'
IFS=':'

그리고 당신은 원하지 않아요전반적인 상황~의 일부분할+전역연산자이므로 다음을 통해 비활성화해야 합니다.

set -f

그래서 그것은 다음과 같습니다:

cond='-name:*.txt'
IFS=:; set -f
find . $cond -ls

아니면 이렇게 할 수도 있습니다:

cond='-name *.txt'
set -f
find . $cond -ls

그리고 $IFS기본값이 수정되지 않았다고 가정합니다.

또는 쉘이 배열을 지원하는 경우 스칼라 변수에 의존하고 확장 시 쉘이 배열을 분할할 것으로 기대하는 대신 배열을 사용할 수 있습니다.

이는 ksh93, 또는 다음 mksh에 적용됩니다 .bashzsh

cond=(-name '*.txt') # an array with two elements: "-name" and "*.txt"
find . "${cond[@]}" -ls # elements of the array expanded as separate arguments
                        # to find.

관련 정보