와일드 카드가 포함 된 "찾기"검색에서 숨겨진 파일 및 디렉토리를 제외 / 무시하는 방법은 무엇입니까?


119

시작 ( "일부 텍스트" 앞뒤에 와일드 카드에 주목 )

find . -type f -name '*some text*'

모든 숨겨진 파일과 디렉토리를 어떻게 제외 / 무시할 수 있습니까?

나는 이미 너무 오랫동안 인터넷 검색을 해왔 으며 일부 자두를 발견했습니다! (느낌표) 매개 변수를 사용했지만 방금 작동 한 적합하지 않은 (그리고 비유적인) 예제 는 없습니다 .

배관 | 하는 grep옵션이 될 것이며, 또한 그 예를 환영 것; 그러나 주로 나는 간단한 한 줄 (또는 독립 한 라이너의 커플 같은 명령 줄 목표를 달성하는 다른 방법을 설명)에 관심이 있어요 바로 사용 find.

추신 : 리눅스에서 파일을 찾아서 특정 디렉토리를 제외하면 밀접하게 관련되어있는 것처럼 보이지만 a) 아직 받아 들여지지 않고 b) 관련되어 있지만 다른 점과 구별되지만 c) 영감을 제공하고 혼란을 정확하게 지적 할 수 있습니다!

편집하다

find . \( ! -regex '.*/\..*' \) -type f -name "whatever"작동합니다. 정규식은 "무엇이든, 슬래시, 점, 그 다음에"(즉, 하위 폴더를 포함한 모든 숨겨진 파일 및 폴더)와 "!"를 찾습니다. 정규식을 무효화합니다.


편집에서 요청한 내용은 도움이되지 않지만 내 질문과 대답은 여기를 참조하십시오 : unix.stackexchange.com/q/69164/15760 및 답변의 링크.

답변:


134

숨겨진 파일과 디렉토리를 건너 뛰고 디렉토리의 하위 파일 인 모든 파일을 인쇄합니다.

find . -not -path '*/\.*'

따라서 some text이름이 있는 파일을 찾고 숨겨진 파일과 디렉토리를 건너 뛰려면 다음을 실행하십시오.

find . -not -path '*/\.*' -type f -name '*some text*'

설명:

-path옵션은 검사에게 전체 경로 문자열에 대한 패턴을 실행합니다. *와일드 카드, /디렉토리 구분자, \.점 (특별한 의미를 피하기 위해 이스케이프해야 함) *이며 다른 와일드 카드입니다. -not이 테스트와 일치하는 파일을 선택하지 않음을 의미합니다.

find이전 명령에서 숨겨진 디렉토리를 재귀 적으로 검색하는 것을 피할만큼 똑똑 하지 않다고 생각 하므로 속도가 필요한 경우 다음 -prune과 같이 사용하십시오.

 find . -type d -path '*/\.*' -prune -o -not -name '.*' -type f -name '*some text*' -print

마지막에 당신이 마지막에 그것을 필요 -print로하십시오! 또한, -name '\.*' would be more efficient instead of -path` 인지 확실하지 않습니다 (경로가 하위 경로를 검색하기 때문에 잘 리게됩니다)
artfulrobot

.이 맥락에서 특별한 의미는 무엇입니까 ?
frostschutz

@frostschutz 뒤에 점 find은 현재 디렉토리를 의미합니다. 현재 find디렉토리 아래의 모든 파일과 디렉토리를 봅니다. 이후의 인수 path는 정규 표현식이며, 점은 일반적으로 "모든 문자"를 의미하며, 문자를 의미하기 위해 백 슬래시로 이스케이프해야합니다. 인수 후 -name 하지 않습니다 정규 표현식,하지만 같은 와일드 카드를 확장 ?하고 *쉘이하는 것처럼.
Flimm

2
@frostschutz 사실, 생각해 보니, 나는 .특별한 의미 를 갖는 것에 대해 틀릴 수도 있습니다 .
Flimm

1
@Flimm p, 탈출 할 필요가 없습니다 .. 지금까지 내가 알고 있어요으로 만 이러한 이스케이프해야합니다 *, ?하고 [].
thdoan

10

이것은 BSD, Mac 및 Linux에서도 올바르게 작동하는 도트 파일을 제외하는 몇 가지 방법 중 하나입니다.

find "$PWD" -name ".*" -prune -o -print
  • $PWD 경로가 시작되지 않도록 현재 디렉토리의 전체 경로를 인쇄하십시오. ./
  • -name ".*" -prune 점으로 시작하고 내려 가지 않는 파일 또는 디렉토리와 일치
  • -o -print이전 표현식이 일치하지 않으면 파일 이름을 인쇄하는 것을 의미합니다. 기본적으로 -print또는 -print0다른 모든 표현식을 사용 하면 인쇄되지 않습니다.

"경보 적으로 복잡한"에 대해 설명하고 정교하게하십시오. 이미 주어진 답변과 당신의 대답은 반대로 증거를주는 것 같습니다 ...?
natty에 대해 nutty

2
"경보 적으로 복잡하다"는 아마도 과도한 것입니다. 나는 요점에 도달하기 위해 대답을 바꾸었다. 필자가 게시 한 답변은 이해하기 어렵고 매뉴얼 페이지를주의 깊게 읽지 않으면보기가 어렵다고 생각합니다. GNU find 사용하는 경우 더 많은 가능한 해결책이 있습니다.
eradman

-o ... -print도움이됩니다. 내 사용을 위해 이제 find ... '!' -name . -name '.*' -prune -o ... -print$ PWD를 포함하는 것보다 편리했습니다.
Roger Pate

4
find $DIR -not -path '*/\.*' -type f \( ! -iname ".*" \)

$ DIR 아래의 모든 숨겨진 디렉토리 및 숨겨진 파일을 제외합니다.


이것이 완벽한 해답입니다. 재귀 적으로 모든 파일을 찾지 만 디렉토리 및 숨겨진 파일에 대한 개별 항목은 제외합니다. 감사!
KyleFarris

2

대답 내가 원래 위 내 원래의 질문에 "편집"으로 게시 :

find . \( ! -regex '.*/\..*' \) -type f -name "whatever"작동합니다. 정규식은 "무엇이든, 슬래시, 점, 그 다음에"(즉, 하위 폴더를 포함한 모든 숨겨진 파일 및 폴더)와 "!"를 찾습니다. 정규식을 무효화합니다.


비슷하지만 현재 폴더에만 해당 :find . \( ! -regex './\..*' \) -type f -maxdepth 1 -print
phyatt

2

당신은 그것을 사용할 필요가 없습니다 find. 다음과 같이 쉘 자체에서 globstar를 사용하십시오.

echo **/*foo*

또는:

ls **/*foo*

여기서 **/재귀 적으로 모든 폴더와 이름 *foo*이있는 파일을 나타냅니다 foo.

기본적으로 사용 ls하면 숨겨진 파일과 디렉토리를 제외한 파일 이름이 인쇄됩니다.

글 로빙을 사용하도록 설정하지 않은 경우로 설정하십시오 shopt -s globstar.

참고 : 새로운 글 로빙 옵션 은 Bash 4, zsh 및 유사한 쉘에서 작동합니다.


예:

$ mkdir -vp a/b/c/d
mkdir: created directory 'a'
mkdir: created directory 'a/b'
mkdir: created directory 'a/b/c'
mkdir: created directory 'a/b/c/d'
$ touch a/b/c/d/foo a/b/c/d/bar  a/b/c/d/.foo_hidden a/b/c/d/foo_not_hidden
$ echo **/*foo*
a/b/c/d/foo  a/b/c/d/foo_not_hidden

5
당신은 그럴 필요가 없습니다 ls! echo **/*foo*
케빈 콕스

@kenorb (및 @ kevin-cox). 좀 더 장황 할 수 있습니까? 왜 globstar (= *)가 여기서 작동합니까? 슬래시 / 무엇을합니까?
natty에 대해 nutty

@nuttyaboutnatty /는 폴더를 의미하며 파일 이름과 디렉토리를 구분합니다. *기본적으로 모든 것을 나타냅니다.
kenorb

@ kenorb 예-하지만 그 한 줄짜리가 원래 질문에 어떻게 도움이됩니까?
natty에 관하여 nutty

1
@nuttyaboutnatty 예를 들어 설명을 추가했습니다. 숨겨진 파일을 무시하는 파일을 찾아 도움이됩니다.
kenorb

1

@Flimm의 대답특히 find가 숨겨진 디렉토리로 내려가는 것을 방지하기 때문에 좋습니다 . 나는이 단순화를 선호합니다 :

일반적으로 모든 숨겨진 경로 (일반 파일, 디렉토리 등)를 제외하려면 다음을 수행하십시오.

find <start-point> -path '*/.*' -prune -o <expression> -print

예를 들어, 작업 디렉토리를 시작점 -name '*some text*'으로 사용하고 표현식으로 사용하십시오.

find . -path '*/.*' -prune -o -name '*some text*' -print

@Flimm의 답변이 제안하는 것과 달리 숨겨진 파일이나 숨겨진 디렉토리는 단순한 경우가 아닙니다. -path '*/.*'표현이있는 모든 경로 (일반 파일, 디렉토리 등)에 대한 사실 ., 바로 파일 분리 후 /. 따라서이 줄은 숨겨진 파일과 디렉토리를 모두 제거합니다.

숨겨진 디렉토리를 제외하고 숨겨진 파일을 허용하는 것은 추가 필터가 필요한 경우입니다. -type d잘라내는 식에 포함시킬 위치 입니다.

find <start-point> -type d -path '*/.*' -prune -o <expression> -print 

예를 들면 다음과 같습니다.

find . -type d -path '*/.*' -prune -o -name '*some text*' -print

이 경우 -type d -path '*/.*'입니다 true만 디렉토리에, 그래서 단지 디렉토리가 정리되어 있습니다.


0

find같은 깔끔한 로직 스위치가 있습니다 -and그리고 -not당신은 너무 같은 두 가지 규칙과 일치하는 파일을 찾기 위해 당신의 이점에 사용할 수 있습니다 :

$ touch non_hidden_file.txt .hidden_file.txt somethings/.another_hidden_file.txt                                                 

$ find . -type f -name '*hidden_file*' -and \( -not -name ".*" \)                            
./non_hidden_file.txt

보시다시피, find두 가지 규칙을 사용 -name '*hidden_file*'하고 -and \( -not -name ".*" \)두 조건 모두와 일치하는 파일 이름을 찾으십시오 hidden_file. 괄호 앞에 슬래시를 주목하십시오-괄호 find는 서브 쉘을 정의하는 대신 인수로 괄호를 정의하는 데 사용됩니다.


0
$ pwd
/home/victoria

$ find $(pwd) -maxdepth 1 -type f -not -path '*/\.*' | sort
/home/victoria/new
/home/victoria/new1
/home/victoria/new2
/home/victoria/new3
/home/victoria/new3.md
/home/victoria/new.md
/home/victoria/package.json
/home/victoria/Untitled Document 1
/home/victoria/Untitled Document 2

$ find . -maxdepth 1 -type f -not -path '*/\.*' | sed 's/^\.\///g' | sort
new
new1
new2
new3
new3.md
new.md
package.json
Untitled Document 1
Untitled Document 2

노트:

  • . : 현재 폴더
  • -maxdepth 1재귀 적으로 검색하려면 제거
  • -type f: 디렉토리가 아닌 파일 찾기 ( d)
  • -not -path '*/\.*' : 돌아 오지마 .hidden_files
  • sed 's/^\.\///g': ./결과 목록에서 접두사 제거
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.