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のための無効なオプション名ではbash

回答:


19

免責事項:この回答は特にBashを扱っていますが、その多くはグロブパターンに関する質問に当てはまります!

スター文字(*)はワイルドカードです。代わりになる特定の文字セットがあり、ドット(.)である最初の文字はそれらの1つではありません。これは、Unixファイルシステムがどのように機能するかという理由だけで特別なケースであり、ドットで始まるファイルは「隠されている」と見なされます。つまり、、などのツールcpls、明示的に指示されない限り、それらを「表示」しません。

まず、サンプルデータを作成しましょう。

$ 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 dotglobecho *:その後、与え.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Dravスローン

@DravSloan-提案をありがとう。追加しました。
slm

cp -r foo .あなたはおそらくあなた自身cpをコピーすることを拒否するので、通常は機能しません。(これは標準的なものです)。foocp -R foo/. .cp -R
ステファンシャゼル

1
また、(非常に賢明)の点に注意してくださいzsh含まれていない...の展開に.*。でzsh、パターンが一致しない場合、コマンドは中止されます(かなり賢明に再び)。したがって、一般的な場合、cp foo/{,.}* .非表示または非表示のファイルがない場合は失敗します。
ステファンシャゼル

7
この回答はbashにのみ適用されます。質問者はzshを使用していますがその答えははるかに単純shoptあり、存在しません。
ジル 'SO-悪であるのをやめる'

29

ではzsh、一般的な方法は、使用することですD グロブ修飾子を([D] OTファイルをインクルードします):

cp foo/*(D) .

ありまたはなしでD、zsh globには決して(予想どおり).も含まれないことに注意してください..


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éphaneChazelasのzshの答えは、globを含む単一の式に対して正しいです。ただし、デフォルトですべての式に設定する場合は、使用できます

setopt GLOB_DOTS

~/.zshrc永続的にするためにあなたにそれを入れてください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.