로 끝나는 파일을 찾고 싶지만 및 폴더 _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 . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
답변
사용하다
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 . \( -type f -name \*_peaks.bed -print \) -or \( -type d -and \( -name tmp -or -name scripts \) -and -prune \)
그리고 내가 그것을 조금 잘못 이해하더라도 너무 놀라지 마십시오. 목표가 exec (인쇄 대신) 인 경우에는 대신 대체하십시오.
답변
나를 위해이 솔루션은 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 ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'