!(notThisDir)의 올바른 출력은 무엇입니까? 하나를 제외한 모든 디렉토리 복사

!(notThisDir)의 올바른 출력은 무엇입니까? 하나를 제외한 모든 디렉토리 복사

하나의 파일만 남기고 모두 복사하려면: 저는 보통 표현식 !(noThisFile)(passable shopt -s extglob)을 사용합니다.

현재의 경우 내가 피하고 싶은 것은 .git디렉토리입니다. 놀랍게도 나는 다음을 시도했습니다.

cp -r !(.git) my-target-dir

../그러나 이는 또한 디렉토리의 내용을 완전히 복사합니다.

사실 내가 언제

echo !(.git) 

출력은 다음으로 시작됩니다.

. .. myDir myDir2 myFile myFile2 

를 사용하여 복사할 때 그런 문제가 있었던 기억이 없습니다. 파일 이름을 확인하면 출력에 !(notthisfile) 아무것도 없습니다 .. ..

  • !(.avoidingDir)내 시스템이 및 둘 다 반환하는 .것이 맞습니까 ..?
  • 만약 그것이 맞다면, 이 문제를 피하려면 어떻게 해야 합니까?

답변1

실제로는 꽤 흥미롭습니다. 적어도 Bash 4.4에서는 이 패턴이 dotglob적용되지 않더라도 도트 파일로 확장하기 위해 이 패턴을 사용하는 것 같습니다. 어쩌면 패턴의 선행이 .부정 내부에 있더라도 이를 가져오기에 충분할 수 있습니다.

이것이 올바른지 아닌지 Bash 개발자에게 문의해야 합니다. Bash 5.0에서는 그렇지 않기 때문에 아마 이렇게 해서는 안 됩니다. (그러나 설정하면 및를 dotglob포함한 모든 도트 파일을 계속 얻을 수 있습니다 .)...

.git, and 를 .제외한 모든 것을 얻으려면 and 를 ..명시적으로 무시하도록 패턴을 확장할 수 있습니다 . 즉 , 숨겨진 and 를 사용할 수 있습니다 ....!(.git|.|..)GLOBIGNORE...

$ mkdir .git .dot dir
$ echo !(.git|.|..)
dir .dot
$ GLOBIGNORE=.:..
$ echo !(.git)
dir .dot

GLOBIGNORE( null이 아닌 값으로 설정하면 sum 이 무시 .되지만..만들다 dotglob.)

또는 도트 파일을 표시하지 않으려면 해당 dotglob파일이 비활성화되어 있는지 확인한 다음 *명시적인 제외 없이 를 사용하세요 .git.

$ unset GLOBIGNORE
$ shopt -u dotglob
$ echo *
dir

Zsh는 또한 .set 을 ..사용하는 경우에도 globdotsksh 스타일을 사용하거나 !(.git)Zsh 자체 ^.git또는 *~.git.

답변2

대답은 다음과 같습니다. 상황에 따라 다릅니다.

GLOBIGNORE가 설정되지 않은 경우 glob(모든 glob)은 도트 파일과 일치합니다.그리고bash 옵션 dotglob이 설정되었습니다.

$ mkdir test; cd test; touch .git .one .two file myfile; \
  mkdir .dir .new dir here

test $ ls -a 
.  ..  .dir  dir  here  .new  file  .git  myfile  .one  .two

test $ unset GLOBIGNORE; shopt -s dotglob; echo *
.dir dir file .git here myfile .new .one .two

test $ unset GLOBIGNORE; shopt -u dotglob; echo *
dir file here myfile

test $ unset GLOBIGNORE; shopt -u dotglob; echo .*
. .. .dir .git .new .one .two

따라서 dotglob을 설정하지 않으면 도트 파일이 무시됩니다. .*예를 들어 위에 명시적으로 포함되지 않은 경우.

설정되더라도 .명시적으로 일치해야 합니다...dotglob

에 대한! (.git)

하지만 그렇습니다. "!(.git)"(시작점이 있는 모든 항목과 마찬가지로)은 "." 및 ".." 및 모든 도트 파일의 일치를 트리거합니다.
shopt -u dotglob; echo !(.a); shopt -s dotglob; echo !(.a)
dir file here myfile
. .. .dir dir file .git here myfile .new .one .two

GLOBIGNORE 를 설정하면 포함 및 설정을 피할 수 있습니다 .. ..설정 GLOBIGNORE도 set 되고 dotglob, 설정 해제 GLOBIGNORE도 unset 된다는 점을 기억하세요 dotglob.

test $ shopt -u dotglob; GLOBIGNORE="."; shopt -p dotglob; echo !(.a)
shopt -s dotglob
.dir dir file .git here myfile .new .one .two

test $ shopt -s dotglob; unset GLOBIGNORE; shopt -p dotglob; echo !(.a)   
shopt -u dotglob
dir file here myfile

따라서 해결 방법으로 GLOBIGNORE를 설정하여 .:..및 의 확장을 방지하세요....

관련 정보