ドットで始まる名前のファイルをコピーするにはどうすればよいですか?


26

ディレクトリAの下のすべてのファイルをディレクトリBにコピーしようとしています。ディレクトリAの下のすべてのファイルはドットで始まります。たとえば、

A/.a
A/.b
A/.c

私が使用すると見つけた:cp A/* B、常にエラーが発生します:

cp: cannot stat 'A/*': no such file or directory

それはのためのオプションはありませんようだcplsドットで始まったエントリを処理するには、誰もがそれを修正する方法を考えていますか?

回答:


34

その理由はbash、に*はドット(.)で始まるファイルが含まれていないためです。

走れます

cp A/.* B

コピーし.たり..、サブディレクトリやサブディレクトリを作成しなかったことを警告しますが、これは問題ありません。

または、ドットファイルと通常のファイルを一緒にコピーする場合は、実行します

cp A/.* A/* B

また、実行することができます

shopt -s dotglob
cp A/* B

で動作しますがbash、動作しませんsh

また、サブディレクトリがコピーされることを気にしない場合、これが最も簡単です:

cp -R A/ B

ヒント:ワイルドカードが期待どおりに動作しない場合は、エコーで実行してみてください。例

$ echo A/*
A/file1 A/file2

$ echo A/.*
A/. A/.. A/.hidden1 A/.hidden2

$ echo A/.* A/*
A/. A/.. A/.hidden1 A/.hidden2 A/file1 A/file2

$ shopt -s dotglob
$ echo A/*
A/file1 A/file2 A/.hidden1 A/.hidden2

を使用する場合にのみ問題になります-r。がなければ-r、ディレクトリをスキップします。
ミケル14

そして、私が使用した例も-Rうまく機能するはずです。間違っていると思う場合は、その理由を説明してください。
ミケル14

7

bashの場合、dotglobコピーする前に設定できます

shopt -s dotglob
cp A/* /destination

またはプログラミング言語

$ ruby -rfileutils -e  'Dir[".*"].each {|x| FileUtils.copy(x,"/destination") if File.file?x}'

ドットグロブを設定したくない場合は、

cp A/.* /destination 2>/dev/null

dotglob OPを使用すると、隠されていないファイルもすべてコピーされますが、これは彼が望んでいるものではありません。
-peoro

@peoro、質問をもう一度読んでください。のすべてのファイルAが非表示になります。彼はただそれをコピーしたいだけです。

7

あなたが探しているのは、次のようなものです。

cp A/.??* B/

これはすべてのドットファイルに一致しますが、「。」には一致しません。または「..」。上記のソリューションのほとんどは、再帰的に作業していない限り問題ありません。しかし、次のようなことをしたいとすぐに:

cp -R A/.??* B/

「..」を省略することなく、非ドットファイルを含むすべてを親ディレクトリからコピーします。


1
これは、.aまたはのような単一の文字であるドットファイルを見逃します.x。最短グロブパターンは私が試合を除くすべてのドットファイルがあることを発見した...あります.[^.]*
パボン14

2

私は次を試してみましたが、見つけるだけで動作します...

cp A/.* B/

2
これも通過するA/.A/..へのパラメータとしてcpケースOPに問題となる可能性があり、また、(使用してディレクトリをコピーする必要があるcp -r
peoro

2

それはcpせいではなく、bashです:bashは*すべての隠されていない(つまり、で始まる非.)ファイルで展開します。

Bashは.*(したがってA/.*、あなたの場合)で始まるすべてのファイルで展開されます.が、不幸なことに...おそらくスキップしたいand (現在および親ディレクトリ)も含まれます。(いくつかのオプションを設定した後、zshのような他のシェルにはシェルが含まれず、IIRCもbashすることに注意してください)。

簡単な解決策は削除することができ.、および..マッチしたファイルから、.*このような(非常に)ハックの方法で、:

cp $( for F in A/.*; do echo $F | grep -v "^\.*$"; done ) B

またはこれ(おそらくクリーナー:findコピーするファイルを見つけるために使用します):

cp $( find A -maxdepth 1 -mindepth 1 -name ".*" ) B

しかし、よりクリーンなソリューションを見つけることができるでしょう。


を使用してfor loop、次のgrepような仕事をするためだけに追加のプロセスを 作成する必要があるのはなぜcp A/.*ですか?cp「。」は無視されます および「..」ディレクトリ。

1

すべてがドットで始まる場合は、単に使用しますA/.*

[holt@Michaela test]$ cp A/* B
cp: cannot stat `A/*': No such file or directory

[holt@Michaela test]$ cp A/.* B
cp: omitting directory `A/.'
cp: omitting directory `A/..'
[holt@Michaela test]$ ls -al B
total 8
drwxrwxr-x. 2 holt holt 4096 2011-03-31 16:57 .
drwxrwxr-x. 4 holt holt 4096 2011-03-31 16:57 ..
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .a
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .b
-rw-rw-r--. 1 holt holt    0 2011-03-31 16:57 .c

お役に立てれば!


1

このスクリプトを使用できます

IFS = $ '\ n'; for $(act A -d 1); do cp -R "$ act" B; やった



0

除外する必要があります。および.. cpに渡されたファイルリストから

これは安全です:

ls -1d A/.[a-zA-Z]* | xargs -i cp -rp {} B

0

これは古いスレッドです...しかし、私は常にすべてのファイルをコピーすることができました。「。」で始まるファイル/フォルダーを含む

例では、すべてのファイルとフォルダーをコピーします。

cp -aup /root/.* / backup / root /

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