[linux] 찾기 명령을 사용하지만 두 디렉토리의 파일 제외

로 끝나는 파일을 찾고 싶지만 및 폴더 _peaks.bed에있는 파일은 제외합니다 .tmpscripts

내 명령은 다음과 같습니다.

 find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)

하지만 작동하지 않았습니다. tmpscript폴더 의 파일 은 계속 표시됩니다.

누구든지 이것에 대한 아이디어가 있습니까?



답변

다음과 find같이 지정하는 방법은 다음과 같습니다.

find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"

설명:

  • find . -현재 작업 디렉토리에서 찾기 시작 (기본적으로 재귀 적으로)
  • -type ffind결과에 파일 만 표시 하도록 지정
  • -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찾기에 의해 추가됩니다. 그렇기 때문에 대부분의 경우 표현식에 추가 할 필요가 없습니다. 그리고 -prunetrue를 반환 하므로 “./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'


답변