문제

나는 주어진 예를 잘 이해하지 못한다. man find, 누구든지 나에게 몇 가지 예와 설명을 줄 수 있습니까?정규 표현식을 결합할 수 있나요?


좀 더 자세한 질문은 이렇습니다.

쉘 스크립트를 작성하고, changeall, 다음과 같은 인터페이스를 가지고 있습니다. changeall [-r|-R] "string1" "string2".접미사가 붙은 모든 파일을 찾습니다. .h, .C, .cc, 또는 .cpp 다음 항목을 모두 변경합니다. string1 에게 string2. -r 현재 디렉토리에만 머물거나 하위 디렉토리를 포함하는 옵션입니다.

메모:

  1. 비재귀적인 경우에는 ls 허용되지 않습니다. find 그리고 sed.
  2. 나는 노력했다 find -depth 하지만 지원되지 않았습니다.그래서 혹시나 궁금했는데 -prune 도움이 될 수 있지만 예제를 이해하지 못했습니다. man find.

편집2:과제를 하고 있었는데, 제가 직접 끝내고 싶어서 자세히 질문하지는 않았습니다.이미 완료하고 제출했으므로 이제 질문 전체를 설명할 수 있습니다.그리고 나는 가까스로 사용하지 않고도 과제를 끝낼 수 있었다. -prune, 하지만 어쨌든 배우고 싶습니다.

도움이 되었습니까?

해결책

내가 찾은 것은 혼란에 관한 것입니다 -prune 그것은 행동이라는 것입니다 (좋아요 -print), 테스트가 아닙니다 (좋아요 -name). "해야 할 일"목록을 변경하고 그러나 항상 사실을 반환합니다.

사용하기위한 일반적인 패턴 -prune 이것은 :

find [path] [conditions to prune] -prune -o \
            [your usual conditions] [actions to perform]

당신은 거의 항상 원합니다 -o (논리적 또는) 즉시 -prune, 테스트의 첫 번째 부분 (최대 및 포함 -prune) 돌아올 것입니다 거짓 당신이 실제로 원하는 물건을 위해 (예 : 당신은 ~하지 않다 가지를 잘라 내고 싶다).

예는 다음과 같습니다.

find . -name .snapshot -prune -o -name '*.foo' -print

".snapshot"디렉토리 아래에 있지 않은 "*.foo"파일이 있습니다. 이 예에서 -name .snapshot 구성 [conditions to prune], 그리고 -name '*.foo' -print ~이다 [your usual conditions] 그리고 [actions to perform].

중요한 메모:

  1. 당신이 원하는 것은 결과를 인쇄하는 것입니다. -print 동작. 당신은 일반적으로 ~하지 않다 사용할 때 그렇게하고 싶습니다 -prune.

    Find의 기본 동작은 "및" 전체 표현 -print 행동 이외의 조치가없는 경우 조치 -prune (아이러니하게) 끝에. 그것은 이것을 쓰는 것을 의미합니다 :

    find . -name .snapshot -prune -o -name '*.foo'              # DON'T DO THIS
    

    이것을 작성하는 것과 같습니다.

    find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
    

    이는 또한 가지 치기 디렉토리의 이름을 인쇄한다는 것을 의미합니다. 일반적으로 원하는 것이 아닙니다. 대신 명시 적으로 지정하는 것이 좋습니다 -print 그것이 당신이 원하는 것이라면 행동 :

    find . -name .snapshot -prune -o -name '*.foo' -print       # DO THIS
    
  2. "일반적인 조건"이 자두 상태에 맞는 파일과 일치하는 경우 해당 파일은 ~ 아니다 출력에 포함됩니다. 이것을 고치는 방법은 a를 추가하는 것입니다 -type d 자두 상태에 대한 술어.

    예를 들어, 우리가 시작한 디렉토리를 잘라 내고 싶다고 가정 해 .git (이것은 분명히 다소 고안되어 있습니다. 일반적으로 당신은 이름이 지정된 것을 제거하면됩니다. 바로 그거죠 .git), 그러나 그 외에는 같은 파일을 포함한 모든 파일을보고 싶었습니다. .gitignore. 당신은 이것을 시도 할 수 있습니다 :

    find . -name '.git*' -prune -o -type f -print               # DON'T DO THIS
    

    이것은 할 것입니다 ~ 아니다 포함 .gitignore 출력에서. 고정 된 버전은 다음과 같습니다.

    find . -type d -name '.git*' -prune -o -type f -print       # DO THIS
    

추가 팁 : GNU 버전을 사용하는 경우 find, texinfo 페이지 find 대부분의 GNU 유틸리티에서는 사실입니다.

다른 팁

-프런트는 내림차순을 방해하지 않는다고 조심하십시오 어느 일부 사람들이 말했듯이 디렉토리. 적용되는 테스트와 일치하는 디렉토리로 내려가는 것을 방지합니다. 아마도 몇 가지 예가 도움이 될 것입니다 (regex 예제는 바닥 참조). 너무 길어서 죄송합니다.

$ find . -printf "%y %p\n"    # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh

$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test

$ find . -prune
.

$ find . -name test -prune
./test
./dir1/test
./dir2/test

$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl

$ find . -name test -prune -regex ".*/my.*p.$"
(no results)

$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test

$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py

$ find . -not -regex ".*test.*"                   .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2

일반적으로 Linux에서 우리가하는 일을하는 기본 방식과 우리가 생각하는 방식은 왼쪽에서 오른쪽으로입니다.
그래서 당신은 가서 먼저 찾고있는 것을 쓸 것입니다.

find / -name "*.php"

그런 다음 Enter를 누르고 원하는 디렉토리에서 너무 많은 파일을 얻고 있다는 것을 알게 될 것입니다. 마운트 드라이브를 검색하지 않도록 배제 /미디어를 배제합시다.
이제 다음을 이전 명령에 추가해야합니다.

-print -o -path '/media' -prune

그래서 최종 명령은 다음과 같습니다.

find / -name "*.php" -print -o -path '/media' -prune

............... | <--- 포함 ---> | .................... | <- -------- 제외 ---------> |

이 구조가 훨씬 쉽고 올바른 접근 방식과 관련이 있다고 생각합니다.

다른 답변에 주어진 조언에 추가 (답장을 만들기 위해 담당자가 없습니다) ...

결합 할 때 -prune 다른 표현에서는 다른 표현이 사용되는 것에 따라 행동에 미묘한 차이가 있습니다.

@Laurence Gonsalves의 예제는 ".snapshot"디렉토리 아래에 있지 않은 "*.foo"파일을 찾을 수 있습니다.

find . -name .snapshot -prune -o -name '*.foo' -print

그러나이 약간 다른 짧은 손잡이는 아마도 부주의하게 .snapshot 디렉토리 (및 중첩 된 .snapshot 디렉토리) :-

find . -name .snapshot -prune -o -name '*.foo'

그 이유는 (내 시스템의 인력에 따라) :-

주어진 표현식이 원시 -Exec, -LS, -OK 또는 -Print를 포함하지 않으면 주어진 표현식이 효과적으로 대체됩니다.

(주어진 _expression) -인쇄

즉, 두 번째 예는 다음을 입력하는 것과 동등하여 용어 그룹화를 수정합니다.

find . \( -name .snapshot -prune -o -name '*.foo' \) -print

이것은 적어도 Solaris 5.10에서 볼 수있었습니다. 약 10 년 동안 다양한 풍미 *닉스를 사용한 후, 나는 최근에 이것이 발생하는 이유를 찾았습니다.

Prune은 디렉토리 스위치에서 다시 반복하지 않습니다.

남자 페이지에서

-Depth가 주어지지 않으면 사실; 파일이 디렉토리 인 경우 파일로 내려 가지 마십시오. -Depth가 주어지면 false; 효과가 없습니다.

기본적으로 그것은 어떤 하위 디렉토리에도 거부하지 않을 것입니다.

이 예를 들어보세요 :

다음 디렉토리가 있습니다

  • /home/test2
  • /home/test2/test2

당신이 달리면 find -name test2:

두 디렉토리를 모두 반환합니다

당신이 달리면 find -name test2 -prune:

/home/test2로 내려 가지 않으므로/home/test2/home/test2/test2로 돌아갑니다.

나는 이것에 대한 전문가가 아닙니다 (그리고이 페이지는 매우 도움이되었습니다. http://mywiki.wooledge.org/usingfind)

방금 눈치 채 셨습니다 -path 그 길을위한 것입니다 바로 뒤에 오는 문자열/경로와 완전히 일치합니다. find (. 이 예에서는) 어디서 -name 모든베이스 이름과 일치합니다.

find . -path ./.git  -prune -o -name file  -print

현재 디렉토리에서 .git 디렉토리를 차단합니다 ( 당신의 발견으로 . )

find . -name .git  -prune -o -name file  -print

모든 .git 하위 디렉토리를 재귀 적으로 차단합니다.

참고 ./ 매우 중요합니다 !! -path 고정 된 경로와 일치해야합니다 . 또는 찾은 직후에 오는 것은 무엇이든 당신이 그것과 일치하는 경우 (OR의 다른 쪽에서 '-o') 가지 치기가 없을 것입니다! 나는 이것을 순진하게 알지 못했고 동일한베이스 이름으로 모든 하위 디렉토리를 가지고 싶지 않을 때 훌륭 할 때 -Path를 사용하게된다 : D

긴 지루한 내용물이 아닌 DIR 자체를 포함한 모든 것을 보여줍니다.

find . -print -name dir -prune

여기에서 좋은 답변을 모두 읽으면 이제 다음 내용이 모두 동일한 결과를 반환한다는 것을 이해했습니다.

find . -path ./dir1\*  -prune -o -print

find . -path ./dir1  -prune -o -print

find . -path ./dir1\*  -o -print
#look no prune at all!

하지만 마지막 것은 여전히 ​​dir1의 모든 것을 검색하기 때문에 훨씬 더 오래 걸릴 것입니다.진짜 질문은 어떻게 하느냐는 것 같아요 -or 실제로 검색하지 않고도 원치 않는 결과를 찾아낼 수 있습니다.

그래서 정리는 지난 경기를 괜찮게 여기지 않고 완료로 표시하는 것을 의미한다고 생각합니다.

http://www.gnu.org/software/findutils/manual/html_mono/find.html"그러나 이는 '-prune' 동작의 효과로 인한 것이 아닙니다(이는 추가 하강을 방지할 뿐이며 해당 항목을 무시하도록 보장하지는 않습니다).대신 이 효과는 '-o'를 사용했기 때문에 발생합니다../src/emacs에 대해 "or" 조건의 왼쪽이 성공했으므로 이 특정 파일에 대해 오른쪽('-print')을 평가할 필요가 전혀 없습니다."

find 파일 목록을 작성합니다. 그것은 당신이 제공 한 술어를 각각에 적용하고 통과하는 것을 반환합니다.

이 아이디어는 -prune 결과에서 제외는 실제로 혼란 스러웠습니다. 자두없이 파일을 제외 할 수 있습니다.

find -name 'bad_guy' -o -name 'good_guy' -print  // good_guy

모두 -prune 검색의 동작을 변경하는 것입니다. 현재 일치가 디렉토리 인 경우 "야 find, 당신이 방금 일치하는 파일, 그것에 내려 가지 마십시오. ". 검색 할 파일 목록에서 해당 트리 (파일 자체가 아님)를 제거합니다.

이름이 지정되어야합니다 -dont-descend.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top