glob 패턴을 가진 cp 숨겨진 파일


13

상황 :

$ mkdir foo && touch foo/.test
$ cp foo/* .
zsh: no matches found: foo/*
(or bash : cp: cannot stat foo/*’: No such file or directory)

숨겨진 폴더와 파일로 가득 찬 디렉토리가 있습니다. 무슨 일이 일어나고 있으며 해결책은 무엇입니까?


dotglob로 번역 globdots하여 zsh을 위한 유효하지 않은 옵션의 이름입니다 배쉬 .

답변:


19

면책 조항 :이 답변은 Bash를 구체적으로 다루지 만 그중 많은 부분이 glob 패턴에 관한 질문에 적용됩니다!

별표 ( *)는 와일드 카드입니다. 대신 할 특정 문자 집합이 있으며 첫 번째 문자 인 점 ( .)은 그 중 하나가 아닙니다. 이것은 유닉스 파일 시스템의 작동 방식 때문에 점으로 시작하는 점으로, 특수한 경우입니다. 점으로 시작하는 파일은 "숨겨진"것으로 간주됩니다. 그 말과 같은 도구 즉 cp, ls명시 적으로 그렇게 말하지 않는 등을 "인식"하지 않습니다.

먼저 샘플 데이터를 만들어 봅시다.

$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}

이제 우리는 다음을 갖습니다.

$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3

이제 몇 가지 게임을 해보자. 명령 echo을 사용하여 *주어진 명령에 대해 특정 와일드 카드 ( ) 를 나열 할 수 있습니다.

$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3


$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2

$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

$ echo .dotdir*
.dotdir1 .dotdir2

행동을 바꾸시겠습니까?

명령 shopt -s dotglob을 사용하여 *파일과 같은 파일 regfile1이 일치 하도록 동작을 변경할 수 있습니다 .dotfile1.

bash매뉴얼 페이지 에서 발췌

dotglob If set, bash includes filenames beginning with a `.' in the results 
        of pathname expansion.

예:

$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3

이 명령으로이 동작을 되돌릴 수 있습니다.

$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3

당신의 상황은?

당신은 cp패턴과 일치하는 모든 파일을 복사하고 파일이 없다는 것을 말하고 *있습니다.

$ cp foo/.* .

또는 foo폴더의 모든 것을 원하면이 작업을 수행 할 수 있습니다 .

$ cp foo .

또는 명시적일 수 있습니다.

$ cp foot/.* foo/* .

다음 중괄호 확장을 사용하는보다 컴팩트 한 형태 bash:

$ cp foo/{.,}* .

언제든지 echo트릭을 사용 하여 제안 된 파일 패턴을 확인할 수 있습니다 (별의 일부를 나타내는 멋진 용어입니다).

$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3

또한 파일 디렉토리와 다른 디렉토리를 복사하려는 경우 일반적 으로이 작업을 반복적으로 수행하려고 -R합니다 cp.

$ cp -R foo/. .

1
당신의 사용을 언급 할 수 있습니다 shopt -s dotglob, echo *: 다음 제공.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Drav 슬로안

@DravSloan-제안 해 주셔서 감사합니다. 추가했습니다.
slm

cp -r foo .자체 cp복사 foo를 거부 하므로 일반적으로 작동하지 않습니다 cp -R foo/. .. ( cp -R표준입니다).
Stéphane Chazelas

1
또한 (눈에 띄게) zsh포함 .하고 ..확장 하지 않습니다 .*. 에서 zsh, 패턴이 일치하지 않는 경우, 명령은 (아주 현명 다시) 중단되기 때문에 일반적인 경우에, cp foo/{,.}* .숨겨진 없거나 비 숨겨진 파일이 존재하지 않는 경우는 실패합니다.
Stéphane Chazelas

7
이 답변은 bash에만 적용됩니다. asker는 zsh를 사용하고 있는데 대답은 훨씬 간단 하고 shopt존재하지 않습니다.
Gilles 'SO- 악의를 멈춰라'

30

을 사용 zsh하는 일반적인 방법은 D glob 한정자 를 사용하는 것입니다 ([D] ot 파일 포함).

cp foo/*(D) .

D포함 .하거나 포함 하지 않고 zsh globs에는 nor가 포함 되지 않습니다 ..(예상대로).


4

셸은 *문자를 확인할 때 해당 파일을 숨김으로 처리 하므로 cp이러한 파일 이름을 인수로받지 않습니다.

명시 적으로 지정하여 복사 할 수 있습니다 cp foo/.* .


1

원하는 모든 파일과 디렉토리를 한 곳에서 다른 곳으로 복사하는 것이라면 표준 rsync명령을 사용할 수 있습니다 . 위의 예에서 당신은 위에주었습니다 :

mkdir foo && touch foo/.test
rsync -a foo/ .

foo숨겨진 파일 및 숨겨진 디렉토리를 포함한 의 모든 내용을 현재 디렉토리로 재귀 적으로 복사합니다 . 마지막 끝에 슬래시 foo/가 rsync에 중요합니다. 그것으로 그것의 내용 만 foo복사되고, 그것 없이는 rsync도 복사 foo됩니다. 예를 들면 다음과 같습니다.

mkdir src && mkdir dest && touch src/.test
rsync -a src  dest    // copies 'src' contents to 'dest/src'
rsync -a src/ dest    // copies 'src' contents to 'dest' 

머신 간 복사를 포함하여 rsync를 조정할 수있는 다른 많은 옵션이 있습니다.


1

Stéphane Chazelas의 zsh 답변 은 글로브가있는 단일 표현에 적합합니다. 그러나 기본적으로 모든 표현식에 대해 설정하려는 경우

setopt GLOB_DOTS

~/.zshrc그것을 영구적으로 만들기 위해 당신의 넣어 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.