로 끝나는 파일을 찾고 싶지만 및 폴더 _peaks.bed
에있는 파일은 제외합니다 .tmp
scripts
내 명령은 다음과 같습니다.
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
하지만 작동하지 않았습니다. tmp
및 script
폴더 의 파일 은 계속 표시됩니다.
누구든지 이것에 대한 아이디어가 있습니까?
답변:
다음과 find
같이 지정하는 방법은 다음과 같습니다.
find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"
설명:
find .
-현재 작업 디렉토리에서 찾기 시작 (기본적으로 재귀 적으로)-type f
- find
결과에 파일 만 표시 하도록 지정-name "*_peaks.bed"
-이름으로 끝나는 파일을 찾습니다. _peaks.bed
! -path "./tmp/*"
-경로가 다음으로 시작하는 모든 결과 제외 ./tmp/
! -path "./scripts/*"
-경로가 다음으로 시작하는 모든 결과를 제외합니다. ./scripts/
솔루션 테스트 :
$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"
./d/4
./c/3
./e/a
./e/b
./e/5
당신은 꽤 가까웠습니다.이 -name
옵션 -path
은 전체 경로를 고려하는 기본 이름 만 고려합니다 =)
find
하지만 질문에 Linux 태그가 지정되어 있으므로 문제가되지 않습니다. 좋은 대답입니다.
.
초기 찾기 프롬프트에서 사용하는 경우 제외하는 각 경로에서 사용해야합니다. 경로 일치는 매우 엄격하며 퍼지 검색을 수행하지 않습니다. 따라서 사용 find / -type f -name *.bed" ! -path "./tmp/"
하면 작동하지 않습니다. 당신 ! -path "/tmp"
은 그것을 행복하게 만들어야합니다.
$ ! -path "./directory/*"
-prune
모든 파일을 확인 하는 대신 사용 하십시오." 제외 된 디렉토리가 매우 깊게 실행되거나 많은 파일이 있고 성능에 관심이 있다면 -prune
대신 옵션 을 사용하십시오 .
할 수있는 한 가지 방법이 있습니다 ...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
find
GNU에서만이 아니라 모든 버전에서 작업 할 수있는 장점이 있습니다 find
. 그러나 문제는 Linux로 태그되어 있으므로 중요하지 않습니다.
사용하다
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
또는
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
또는
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
순서가 중요합니다. 왼쪽에서 오른쪽으로 평가됩니다. 항상 경로 제외로 시작하십시오.
전체 디렉토리를 제외하기 위해 -not
(또는 !
)을 사용하지 마십시오 . 사용 -prune
. 설명서에 설명 된대로 :
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
그리고 GNU에서 매뉴얼 찾기 :
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
실제로를 사용 -not -path "./pathname"
하면 find는 아래의 각 노드에 대한 표현식을 평가합니다 "./pathname"
.
찾기 표현식은 조건 평가 일뿐입니다.
\( \)
-그룹 작업 (을 사용할 수 -path "./tmp" -prune -o -path "./scripts" -prune -o
있지만 더 자세합니다).-path "./script" -prune
-true를 -path
반환하고 디렉토리이면 해당 디렉토리에 대해 true를 반환하고 그 디렉토리 로 내려 가지 마십시오 .-path "./script" ! -prune
- (-path "./script") AND (! -prune)
. prune의 "항상 참"을 항상 거짓으로 되돌립니다. "./script"
일치로 인쇄하지 않습니다 .-path "./script" -prune -false
- -prune
항상 true를 반환 -false
하기 때문에 !
.-o
-OR 연산자. 두 표현식 사이에 연산자가 지정되지 않은 경우 기본값은 AND 연산자입니다.따라서 다음 \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
으로 확장됩니다.
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
인쇄가 없으면 다음으로 확장되기 때문에 여기서 중요합니다.
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
찾기에 의해 추가됩니다. 그렇기 때문에 대부분의 경우 표현식에 추가 할 필요가 없습니다. 그리고 -prune
true를 반환 하므로 "./script"및 "./tmp"가 인쇄됩니다.
-prune
항상 false를 반환하도록 전환했기 때문에 다른 것에서는 필요하지 않습니다 .
힌트 :를 사용 find -D opt expr 2>&1 1>/dev/null
하여 최적화 및 확장 방법
find -D search expr 2>&1 1>/dev/null
을 확인하고 어떤 경로가 확인되었는지 확인할 수 있습니다.
나를 위해이 솔루션은 find 명령 exec에서 작동하지 않았으므로 이유를 모르겠습니다. 그래서 내 솔루션은
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
설명 : sampson-chen과 동일하며
-prune-진행 경로 무시 ...
-o-일치하지 않으면 결과를 인쇄합니다 (디렉토리를 정리하고 나머지 결과를 인쇄).
18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3: 0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4: 0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5: 0.0% -- replaced with ./e/5.gz
./e/a: 0.0% -- replaced with ./e/a.gz
./e/b: 0.0% -- replaced with ./e/b.gz
find . -path ./scripts -prune -name '*_peaks.bed' -type f
. 여러 디렉터리를 제외하는 방법을 잘 모르겠습니다. type
지정된 경우에도 최상위 제외 디렉토리도 나열 됩니다. prune을 사용하여 찾기 작업의 속도를 높이고 싶지 않으면 Grep을 통해 제외하는 것이 더 간단 해 보입니다.
_peaks.bed
.