find는 하나의 명령으로 여러 이름과 경로를 결합합니다.

find는 하나의 명령으로 여러 이름과 경로를 결합합니다.

찾아서 반응해야 하는 상당히 복잡한 파일 세트가 있습니다(예: 텍스트 파일에 복사된 경로).

예를 들어:

 find / \( -iname "*ssh*" -or -iname "*scp*" \) \( -not -path -"/run" -not -path "/rw/*" -and -not -path "/home/*" -and -not -path "*/qml/*" \) >> ~/files.txt

여기서는 "ssh" 및 "scp"와 관련된 모든 파일이나 폴더를 찾고 싶지만 /run 또는 /rw 디렉터리에서는 찾을 수 없습니다.

여기에 더 많은 조건을 추가하고 싶지만 명령이 너무 깁니다. 정규식으로 이 작업을 어떻게 수행할 수 있나요?

답변1

다음을 사용하여 해당 디렉토리에 있는 파일을 필터링하는 것보다 전혀 제외하려는 디렉토리에 들어가지 않는 것이 좋습니다 ! -path <pattern>.

LC_ALL=C find / \
       '(' \
          -path /run -o  -path /rw -o -path /home -o -path '*/qml' \
       ')' -prune -o '(' \
          -name '*[sS][hH][hH]*' -o -name '*[sS][cC][pP]*' \
       ')' -print

여기서는 POSIX 구문이 사용됩니다 find. GNU의 경우 find다음과 같을 수 있습니다.

LC_ALL=C find / -regextype posix-extended \
  -regex '/home|/rw|.*/qml' -prune -o \
  -iregex '.*s(cp|sh)[^/]*' -print

BSD를 사용하면 다음 과 같은 것을 사용하여 POSIX ERE를 얻을 수 있습니다 find.-Egrepsed

LC_ALL=C find -E / \
  -regex '/home|/rw|.*/qml' -prune -o \
  -iregex '.*s(cp|sh)[^/]*' -print

답변2

여기에 줄바꿈이 있는 버전이 있어 읽기가 더 쉽고 일부 오타가 수정되었습니다. 나는 GNU 조회를 가정하고 있지만 약간의 수정은 대부분의 BSD 조회에서도 작동할 것입니다.

find / \
     \( -iname "*ssh*" -or -iname "*scp*" \) \
     \( -not -path "/run/*" \
        -not -path "/rw/*" \
        -not -path "/home/*" \
        -not -path "*/qml/*" \) \
     >> ~/files.txt

이제 조금 단순화하기 위해 -iname "*ssh*" -or -iname "*scp*"정규식으로 작성할 수 있습니다. 예를 들면 다음과 같습니다.

find ... \
     -regextype posix-extended \
     -iregex '.*(ssh|scp)[^/]*' \
     ...

이제 이름을 더 쉽게 추가할 수 있습니다 (ssh|scp|rsync|...).

이러한 -not -path테스트는 다음과 같이 정규식으로 결합될 수 있습니다.

find ... \
     -not -regex '(/run|/rw|/home|.*/qml)/.*'

그러나 find다음을 사용하지 않으면 이러한 디렉토리를 탐색하는 데 여전히 많은 시간을 낭비하게 됩니다 -prune.

find / \
     -regextype posix-extended \
     -not \( -regex '(/run|/rw|/home|.*/qml)/.*' -prune \) \
     -iregex '.*(ssh|scp)[^/]*' \
     >> ~/files.txt

관련 정보