쉘 와일드카드에서 0개 이상의 연산자를 일치시킵니다.

쉘 와일드카드에서 0개 이상의 연산자를 일치시킵니다.

*나는 여기서 매우 사소한 문제에 봉착했습니다: bash에서 기호를 의미있게 만드는 방법0 이상, 도구에서처럼요 sed?

예를 들어, 이름 ak*전체가 a0개 이상의 s로 k구성된 파일은 모두 일치해야 합니다. 확장자에는 , 및 가 포함되지만 aak포함 akk되지 akkk않습니다 akc.

나는 이것을 unsetopt sh_globzsh와 set -o noglobbash에서 시도했지만 예상된 동작을 생성하지 않습니다.

답변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. extglobUbuntu 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

관련 정보