이름-경로 찾기

이름-경로 찾기

나에겐 나무가 있다.

.
├── 1
│   └── a
│       └── script.a.sh
├── 2
│   └── a
│       └── script.b.sh
...
└── a
    └── script.sh

나는 찾아야 한다 script.*.sh. 나는 다음을 실행한다 ./a/script.sh:

#!/bin/bash
#

path="/tmp/test"

readarray files < <(find ${path} -path  "*/a/script.*.sh")

if [ ${#files[@]} -ne 0 ]
then
  for file in "${files[@]}"
  do
    echo ${file}
  done
fi

산출:

/tmp/test/1/a/script.a.sh
/tmp/test/2/a/script.b.sh

이것은 유효한 스크립트입니다!

find ${path} -path "*/a" -name "script.*.sh"하지만 find 명령을 스크립트 로 변경하면 아무 것도 출력되지 않습니다.

내 논리는 /tmp/test/*/a/script.*.sh내가 말하는 패턴을 가진 모든 파일을 찾습니다 find ${path} -path "*/a" -name "script.*.sh".

현재 남은 질문은 다음과 같습니다.

  1. find ${path} -path "*/a" -name "script.*.sh"명령은 실제로 무엇을 수행합니까?
  2. 에 디버그 모드가 있나요 find? 내 말은 내가 말하는 내용을 어떻게 이해하는지를 의미합니다(예: 검색할 경로, no find . -name "*te.st*", just ./*/*te.st*).
  3. -name, 동일한 명령줄(필요한 사례, 예, 설명)에 있을 수 있습니까 -path? 아니면 상호 배타적입니까? 아니면 -path확장 버전 이라고 할 수 있나요 -name?

man여러분, 네, 그리고 를 사용할 수 있습니다 google. 또한 이러한 출처에서 모든 질문에 대한 완전한 답변을 찾지 못했습니다.

답변1

-pathGNU 버전의 인수는 find시작 디렉터리를 포함하여 액세스되는 개체의 전체 경로에 적용되는 패턴을 지정합니다.

패턴은 패턴이지만 슬래시는 특별하게 취급되지 않습니다. 예를 들어 경로 a/b/c/d및 패턴 일치입니다 a*d.

이는 쉘 문의 case패턴 일치 와 유사합니다.

$ case a/b/c/d in a*d ) echo match;; esac
match

경로 이름 확장에서 패턴 일치 대신.

$ echo a*d # will not match an a/b/c/d file accessible in this directory!

예를 들면 다음과 같습니다.

find /etc -path '*.conf'

일치하고 인쇄됩니다 /etc/foobar/foobar.conf. 경로를 만나면 경로가 패턴과 일치합니다.

그러므로:

  1. 질문: find ${path} -path "*/a" -name "script.*.sh"무엇을 하시겠습니까?

    대답: 아무것도 찾지 못할 것입니다. -path로 끝나는 경로와 일치하므로 /a로 끝나는 script.*.sh디렉터리 항목을 일치시키는 것은 불가능합니다 a. -pathand 조건자는 -name암시적 논리 AND로 연결되므로 결과는 비어 있습니다.

  2. 시작 위치는 선택 사항입니다 . 생략 find할 수 있습니다 . 쉘 구문 (인용 부호가 없는 인수로 사용되는 경우)은 파일 이름 확장을 사용하여 쉘에 의해 확장됩니다. 또는 일치하는 항목이 없으면 그대로 둘 수도 있습니다.find -name '*.txt'find . -name '*.txt'./*/*te.st*find

  3. -pathQ: 라이브 와 -name동일한 명령줄에 있을 수 있나요 ?

    답변: 물론 가능합니다. 하지만 "and"와 결합하여 충돌이 발생하면 결과가 비어 있을 수 있습니다. find -path X -name Y의미 find -path X -a -name Y -a -print: 액세스한 경로가 일치하지 않는 X경우그리고액세스되는 디렉토리 항목이 와 일치하면 Y경로가 인쇄됩니다. X일치하는 name 으로 끝나는 Y일치 하는 경로가 없으면 -print조건자(암시적 또는 명시적)에 도달할 수 없습니다. 아무것도 인쇄될 수 없습니다.

답변2

find ${path} -path "*/a" -name "script.*.sh"하지만 find 명령을 스크립트 로 변경하면 아무 것도 출력되지 않습니다.

실제로는 그렇지 않습니다. 조건자와 일치하는 파일은 -path "*/a"조건자와도 일치할 수 없습니다 -name "script.*.sh".

내 논리는 /tmp/test/*/a/script.*.sh내가 말하는 패턴을 가진 모든 파일을 찾습니다 find ${path} -path "*/a" -name "script.*.sh".

당신이 가정하고 있는 $path값 은 /tmp/test. 이 경우에는 왜 일을 그렇게 복잡하게 만드는지 잘 모르겠습니다. glob을 통해 원하는 경로를 정확하게 설명할 수 있으므로 find완전히 생략하고 싶습니다.

files=("${path}"/*/a/script.*.sh)

하지만 이 작업을 수행하려면 find이 경우 합계를 결합하는 것이 의미가 없습니다 -name. -path이미 관찰한 것처럼 원래 find명령이 작업을 수행합니다. 그리고 더 간단하고 명확합니다.

또는 부분 경로 일치를 원본 목록으로 이동할 수 있습니다.

find ${path}/*/a -maxdepth 1 -name  "*script.*.sh"
  1. find ${path} -path "*/a" -name "script.*.sh"명령은 실제로 무엇을 수행합니까?

${path}루트에 루트가 있는 하위 트리에서 경로(로 시작 ${path})가 패턴과 일치하고 */a기본 이름이 패턴과 일치하는 파일을 검색합니다 script.*.sh. 각각 완료되었습니다. 이 두 조건을 충족하는 모든 파일의 경로가 인쇄되지만 동일한 파일이 동시에 두 조건을 모두 충족할 수 없으므로 아무 것도 인쇄되지 않습니다.

  1. 에 디버그 모드가 있나요 find? 내 말은 내가 말하는 내용을 어떻게 이해하는지를 의미합니다(예: 검색할 경로, no find . -name "*te.st*", just ./*/*te.st*).

POSIX에는 디버깅 도구가 지정되어 있지 않지만 findutils 와 findutils를 모두 find태그했기 때문에 GNU findutils 버전을 사용하고 있는 것이 거의 확실합니다 . 이 구현linuxubuntufind하다디버깅 도구가 문서화되어 있습니다.맨페이지. 당신은 이 옵션을 찾고 있습니다 -D. 얼마나 도움이 될지는 확실하지 않지만 최대 디버깅 정보를 얻으려면 -D all시작점 목록 앞에 명령을 추가할 수 있습니다.find

  1. -name, 동일한 명령줄(필요한 사례, 예, 설명)에 있을 수 있습니까 -path? 아니면 상호 배타적입니까? 아니면 -path확장 버전 이라고 할 수 있나요 -name?

예, 함께 사용할 수 있으며 때로는 결합하는 것이 합리적일 수도 있습니다. 하지만 당신을 혼란스럽게 할 수 있는 것은

  • 그들은독립적인, 그리고
  • -path시험모두디렉토리 부분뿐만 아니라 경로. 아마 당신 -path이 그랬냐고 물었을 때의 상황은 그랬을 것입니다 -name.

-path조건자가 실제로 선택하려는 파일과 일치하지 않기 때문에 결합하려는 시도가 실패합니다 . 그러나 이것은 작동합니다:

find ${path} -path  "*/a/*" -name "script.*.sh"

-o-a또한, 암묵적이거나 명시적인("and") 대신 연결사("또는"을 의미)를 사용하거나 하나 또는 두 술어를 부정하는 조합에서 더 많이 사용될 수 있습니다 -not.

관련 정보