이름이 두 패턴과 일치하는 Bash에서 모든 파일을 열거나 나열하는 방법

이름이 두 패턴과 일치하는 Bash에서 모든 파일을 열거나 나열하는 방법

수천 개의 파일이 있는 디렉토리가 있다고 가정해 보겠습니다. 이름에 "red"와 "green"이라는 문자열이 모두 포함된 모든 파일을 어떻게 열 수 있습니까?

답변1

find . -type f -name '*red*' -name '*green*'  -exec echo {} +

또는 파일을 여는 데 사용하려는 명령 echo으로 바꾸십시오 .vigvimless

일부 프로그램은 명령줄에서 여러 파일 이름을 처리할 수 없습니다. 선택한 프로그램이 이들 중 하나인 경우 +줄 끝을 로 바꾸십시오 \;. 이렇게 하면 긴 파일 이름 목록에 대해 한 번만 실행되는 것이 아니라 각 파일 이름에 대해 한 번만 명령이 실행됩니다.

xdg-open그것이 순서입니다. 열도록 요청된 파일 형식을 감지한 다음 시스템 기본 프로그램(또는 기본 프로그램을 재정의한 경우 선호하는 프로그램)을 사용하여 파일을 엽니다. 파일 형식을 인식하지 못하면 파일을 열 때 무엇을 사용해야 하는지 묻습니다.

이와 같이 사용하는 것은 find유용하지만 동시에 성가신 일이기도 합니다. 시도해 보면 그 이유를 알 수 있습니다(일치하는 파일 이름에 대해 하나씩 차례로 많은 창이 열리는 것을 볼 수 있습니다).

find . -type f -name '*red*' -name '*green*' -exec xdg-open {} \;

그런데 일치하는 파일을 찾고 싶다면*red* 또는 *green*-a의 경우 괄호를 사용하여 "and"( ) 및 "or"( -o) 연산자 의 우선 순위를 지정해야 합니다 . 그런데 find위에서 여러 조건자를 사용하여 실행할 때 기본 연산자는 a 입니다 -a. 즉, 조건자는 AND로 논리적으로 결합됩니다.

괄호는 쉘에서 특별한 의미를 갖기 때문에 쉘에서 해석되지 않고 find 명령에 전달되도록 백슬래시로 이스케이프 처리해야 합니다.

find . -type f \( -name '*red*' -o -name '*green*' \) -exec echo {} +

이것을 "일반 파일 AND ('*red*' 또는 '*green*'과 일치하는 파일 이름)"로 읽습니다.

답변2

그리고 zsh:

set -o extendedglob # best in ~/.zshrc
ls -ld -- *green*~^*red*

glob ~연산자는 다음 용도로 사용됩니다.와는 별개로(설마). ^이다아니요. 그래서 조합은아니 아니, 그래서그리고. IOW, green파일 이름의 파일과 일치합니다.와는 별개로하는 사람들아니요포함하다 red.

부정 연산자를 사용하는 대안 ^(필수 extendedglob):

ls -ld -- ^(^*green*|^*red*)

녹색을 포함하지 않거나 빨간색을 포함하지 않는 파일을 제외한 모든 것.

숨겨진 파일도 포함하려면 (D)glob 한정자를 추가하세요.

또한 glob 한정자를 사용하여 파일 이름을 정규 표현식과 일치시킬 수 있으며 를 사용하면 setopt rematchpcre이러한 정규 표현식 PCRE를 만들 수 있습니다.그리고:

re() {
  setopt localoptions rematchpcre
  [[ $REPLY =~ $1 ]]
}
ls -ld -- *(e['re "^(?=.*green).*red"'])

또는:

re() {
  setopt localoptions rematchpcre
  [[ $REPLY =~ $RE ]]
}
RE='^(?=.*green).*red'; ls -ld -- *(+re)

(PCRE는 텍스트가 아닌 문자열을 차단하며 모든 멀티바이트 텍스트 인코딩을 지원하지 않습니다.)

그리고 ksh또는 bash -O extglob또는zsh -o kshglob

ls -ld -- !(!(*green*)|!(*red*))

!(pattern)확장된 전역 연산자와 동일합니다 ksh.zsh^pattern

다음과 같이 할 수도 있습니다.

ls -ld -- @(*green*red*|*red*green*)

그러나 이는 어떤 모델에도 일반화되지 않습니다. 예를 들어, abcand 가 포함된 파일 의 경우 파일 일치를 수행하려면 , ... bcd이 필요합니다 .@(*abc*bcd*|*abcd*|*bcd*abc*)???*x*@(x??|?x?|??x)

그리고ksh93

ksh93일부가 있습니다그리고와일드카드 연산자:

ls -ld -- @(*green*&*red*)

아니면 그것을 사용향상된정규 표현식(glob 연산자로 도입됨 ~(A:...)):

ls -ld -- ~(A:.*green.*&.*red.*)

perl-like다음에서 예측 연산자를 사용할 수도 있습니다 ksh93.

ls -ld -- ~(P:(?=.*green).*red.*)

답변3

(파일을 찾고 있다고 가정합니다.이름포함하다둘 다문자열 "빨간색"그리고문자열 "녹색")

=~정규식 일치 연산자를 사용하여 파일 이름의 "빨간색" 및 "녹색"을 테스트하기 위해 bash를 무의미하게 사용하려면 다음을 수행하십시오.

for f in *
do
  [[ $f =~ red && $f =~ green ]] && echo Bash: yes: "$f" || echo Bash: no: "$f"
done

표준 쉘 구문을 사용하려면 caseglob을 사용하여 동일한 파일을 찾으십시오.

for f in *
do 
  case "$f" in
    *green*red*|*red*green*) echo Case: yes: $f;; 
    *) echo Case: no: $f;; 
  esac
done

더 간단하게는 쉘 와일드카드를 사용하는 것입니다:

printf "Glob: %s\n" *green*red* *red*green*

실행 예시:

$ touch a b aredgreenb agreenredb agreenbred aredbgreen red green redgreen greenred

$ for f in *
>     do
>       [[ $f =~ red && $f =~ green ]] && echo Bash: yes: "$f" || echo Bash: no: "$f"
>     done
Bash: no: a
Bash: yes: agreenbred
Bash: yes: agreenredb
Bash: yes: aredbgreen
Bash: yes: aredgreenb
Bash: no: b
Bash: no: green
Bash: yes: greenred
Bash: no: red
Bash: yes: redgreen


$ for f in *
>     do
>       case "$f" in
>         *green*red*|*red*green*) echo Case: yes: $f;;
>         *) echo Case: no: $f;;
>       esac
>     done
Case: no: a
Case: yes: agreenbred
Case: yes: agreenredb
Case: yes: aredbgreen
Case: yes: aredgreenb
Case: no: b
Case: no: green
Case: yes: greenred
Case: no: red
Case: yes: redgreen

$ printf "Glob: %s\n" *green*red* *red*green*
Glob: agreenbred
Glob: agreenredb
Glob: greenred
Glob: aredbgreen
Glob: aredgreenb
Glob: redgreen

답변4

open명령이 여러 인수를 처리할 수 있다고 가정하면 간단합니다 .

open *red* *green*

편집: 죄송합니다. 질문을 (이름이 빨간색인 파일) 및 (이름이 녹색인 파일)로 읽고 있었습니다.

다음은 extglob을 사용하고 이름이 다음과 같은 파일의 경우 이중 계산을 방지합니다 redgreenred.

$ shopt -s extglob     # turn on extended globbing
$ printf "extglob: %s\n" @(*green*red*|*red*green*)
extglob: agreenbred
extglob: agreenredb
extglob: aredbgreen
extglob: aredgreenb
extglob: greenred
extglob: redgreen
extglob: redgreenred
$ shopt -u extglob     # turn off extended globbing

관련 정보