수천 개의 파일이 있는 디렉토리가 있다고 가정해 보겠습니다. 이름에 "red"와 "green"이라는 문자열이 모두 포함된 모든 파일을 어떻게 열 수 있습니까?
답변1
find . -type f -name '*red*' -name '*green*' -exec echo {} +
또는 파일을 여는 데 사용하려는 명령 echo
으로 바꾸십시오 .vi
gvim
less
일부 프로그램은 명령줄에서 여러 파일 이름을 처리할 수 없습니다. 선택한 프로그램이 이들 중 하나인 경우 +
줄 끝을 로 바꾸십시오 \;
. 이렇게 하면 긴 파일 이름 목록에 대해 한 번만 실행되는 것이 아니라 각 파일 이름에 대해 한 번만 명령이 실행됩니다.
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*)
그러나 이는 어떤 모델에도 일반화되지 않습니다. 예를 들어, abc
and 가 포함된 파일 의 경우 파일 일치를 수행하려면 , ... 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
표준 쉘 구문을 사용하려면 case
glob을 사용하여 동일한 파일을 찾으십시오.
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