찾아서 반응해야 하는 상당히 복잡한 파일 세트가 있습니다(예: 텍스트 파일에 복사된 경로).
예를 들어:
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
.-E
grep
sed
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