*
나는 여기서 매우 사소한 문제에 봉착했습니다: bash에서 기호를 의미있게 만드는 방법0 이상, 도구에서처럼요 sed
?
예를 들어, 이름 ak*
전체가 a
0개 이상의 s로 k
구성된 파일은 모두 일치해야 합니다. 확장자에는 , 및 가 포함되지만 a
는 ak
포함 akk
되지 akkk
않습니다 akc
.
나는 이것을 unsetopt sh_glob
zsh와 set -o noglob
bash에서 시도했지만 예상된 동작을 생성하지 않습니다.
답변1
와는 별개로ksh93
, 일반적으로 사용되는 쉘에는 파일 일치에 사용할 수 있는 sed, awk 등과 동일한 구문을 가진 정규식이 없습니다.
Ksh93, bash 및 zsh는 구문이 다른 정규 표현식을 가지며 glob과 역호환됩니다.
?
단일 문자와 일치합니다(.
일반적인 정규식 구문과 동일).[…]
거의 같은 방식으로 문자 집합을 일치시킵니다.*(FOO)
임의의 발생 횟수 일치FOO
(일반적인 정규식 구문과 동일)(FOO)*
- 또한 하나 이상의 항목과 일치하며 0개 또는 1개의 항목과 일치합니다.
+(FOO)
?(FOO)
@(FOO|BAR)
일치FOO
하거나BAR
- 하위 문자열이 아닌 전체 문자열에 대해 일치가 작동합니다. 하위 문자열을 원할 경우
*
시작과 끝에 넣으세요.
shopt -s extglob
이 구문을 사용하려면 bash 및 zsh에서 활성화해야 합니다 setopt ksh_glob
. 그래서 bash에서는 다음과 같이 쓸 것입니다.
shopt -s extglob
ls a*(k)
당신은 또한 볼 수 있습니다내 정규 표현식이 X에서는 작동하지만 Y에서는 작동하지 않는 이유는 무엇입니까?
=~
Ksh93, zsh 및 bash는 확장 정규식(기본적으로 awk 구문)이 포함된 생성된 연산자를 사용하여 문자열에 대한 정규식 일치를 수행할 수 있습니다 [[ … ]]
. 이는 파일 목록을 표시하는 데 불편하지만 정말로 원할 경우 수행할 수 있습니다.
shopt -s dotglob # <<< include dot files, for bash
setopt globdots # <<< include dot files, for zsh
FIGNORE='@(.|..)' # <<< include dot files, for ksh
for x in *; do
if [[ $x =~ ^ak*$ ]]; then
…
fi
done
답변2
ls ak{k,}
ak
로 시작하는 파일이 표시 되고 그 뒤에 다른 파일이 표시되거나 k
파일이 표시되지 않습니다.
$ touch ak akk akc
$ ls -l ak{k,}
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 ak
-rw-rw-r-- 1 cas cas 0 Oct 27 10:30 akk
glob은 정규 표현식이 아니지만 단순한 *
and 이상의 기능을 합니다 ?
.
정규식을 사용하여 일치하는 파일 이름을 찾으려면 다음 find
명령을 사용할 수 있습니다.
$ find . -maxdepth 1 -type f -regex './ak+$'
./ak
./akk
이 -maxdepth 1
옵션은 검색을 현재 디렉터리로만 제한합니다(하위 디렉터리는 검색되지 않음).
대소문자를 구분하지 않고 검색하려면 -iregex
대신 를 사용하세요 -regex
.
find
다른 명령에서 찾은 파일을 사용하는 방법에는 여러 가지가 있습니다 . 예를 들어:
find . -maxdepth 1 -type f -regex './ak+$' -ls
find . -maxdepth 1 -type f -regex './ak+$' -exec ls -ld {} +
find . -maxdepth 1 -type f -regex './ak+$' -print0 | xargs -0r ls -ld
ls -ld $(find . -maxdepth 1 -type f -regex './ak+$')
마지막 예는 1. 파일 이름 등의 공백을 처리하지 않음, 2. 명령줄 길이 제한 등 다양한 오류 모드에 취약합니다. 권장되지 않습니다.
답변3
사용할 수 있는 구문은 bash
다음과 같습니다.
ls a+(k)
이는 활성화된 쉘 옵션에 따라 다릅니다 bash
shopt
. extglob
Ubuntu 14.04 GNU/Linux에서는 이것이 기본적으로 활성화되어 있는 것으로 보입니다.
작동 방식은 다음과 같습니다.
$ shopt extglob
extglob on
$ ls
ak akc akd akk akkk akkkk
$ ls a+(k)
ak akk akkk akkkk
$ shopt -u extglob
$ shopt extglob
extglob off
$ ls a+(k)
bash: syntax error near unexpected token `('
$
Bash 매뉴얼에서:
+ (모드 목록)
주어진 패턴과 하나 이상 일치합니다.
패턴 목록은 "|"로 구분된 하나 이상의 패턴 목록입니다.
Bash 매뉴얼을 참조하세요:https://www.gnu.org/software/bash/manual/bash.html#Pattern-Matching.
답변4
쉘에 따른 일부 옵션:
$ touch a akk aka
$ ksh -c 'echo a*(k)'
a akk
$ zsh -o kshglob -o nobareglobqual -c 'echo a*(k)'
a akk
( nobareglobqual
여기서 후행은 (k)
전역 한정자로 간주되지 않습니다)
$ bash -O extglob -c 'echo a*(k)'
a akk
$ zsh -o extendedglob -c 'echo ak#'
a akk
zsh
#
정규 표현식과 동일 합니다 *
.
ksh93
또한 해당 glob에서 다양한 유형의 정규식을 사용할 수 있습니다.
$ ksh93 -c 'echo ~(E:ak*)' # extended RE
a akk
$ ksh93 -c 'echo ~(P:ak*)' # perl-like RE
a akk
$ ksh93 -c 'echo ~(X:ak*)' # AT&T augmented RE
a akk
$ ksh93 -c 'echo @(~(E)ak*)' # alternative syntax
a akk