Linuxで隠しファイル(ドットで始まる)とサブディレクトリをコピーする方法は?


10

フォルダAの隠しファイルと隠しサブディレクトリ(ドットで始まるもの)をフォルダBにコピーする方法は?たとえば、次のような構造の場合:

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

Aの隠しファイルと隠しサブディレクトリだけをBにコピーしたいと思います。

B/.a
B/.b/
B/.b/somefile
B/.b/.c

私はすでに、このコマンドを試してみました:cp A/.* Bからこの他のスーパーユーザの質問。ただし、サブディレクトリはコピーされません。も試しましたcp -r A/.* Bが、コピーされる.ので、Aの正確なコピー(通常のファイルを含む)で終わります。どんな助けでもありがたいです。

回答:


16

たとえば、Aレベルで隠しファイルと隠しフォルダーのみを探していて、不要な場合

A/b/.hidden

コピーするには、これを使用できるはずです:

cp -r A/.[^.]* B

これは基本的に、aで始まるものをすべてコピーし、.次にa以外のすべての文字を.除外して...

編集:所有者や日付などを保持したいことをAskerが示していないため、cpコマンドから-pを削除しました。


これは質問で指定されたサンプルのファイル名とディレクトリ名で機能しますが、質問のテキストには「隠しファイルと隠しサブディレクトリ(ドットで始まるもの)」と書かれており、この回答では名前が次の名前で始まるファイルとディレクトリは見つかりません2つのドット; 例えば、..c
スコット

それはかなりエッジケースですが、それでも正当な懸念です。私はそれを考えていませんでした。に切り替えること.*[^.]でそれを説明できますが、末尾が.。のファイルは見逃してしまいます。本当にすべてのケースを説明するには、本当に拡張グロビングが必要だと思います。
Omnipresence 2014年

4

の問題A/.*は、パターンにも一致するディレクトリ.Aあることです。

拡張グロブパターンをオンにして、以下を使用できます。

shopt -s extglob
cp -r A/.!(?(.)) B    

名前がドットで始まり、2番目の文字がドットでも何でもないファイルに一致します(?(。)は何もまたはドットに一致せず、!(...)はそれを否定します。つまり、!(?(。))は他のすべてに一致します何もないか、ドットより)。


正解は+1。.!(@(|.))(AFAICT)は上記と同等であり、(IMNSHO)は少し明確で、1文字だけ長いことに注意してください。
スコット

3

このような場合は、次のfind代わりに使用することをお勧めしますcp

find A/ -type f -maxdepth 1 -name '.*' -exec cp -p {} B/ \;

基本的な構文は次のように分解されます。

  • find A/ -type f:タイプが(findディレクトリA/ではなく)ファイルであるディレクトリ内のアイテム…
  • -maxdepth 1 -name '.*':これで、maxdepth1のディレクトリの場合、でname始まる.
  • -exec cp -p {} B/ \;:そして、これらのファイルが検出された一回でコマンドのソースからの日付/時刻(保存するためのフラグの目的地への)。execcp-p{}B/

を使用maxdepthしてコントロールのレイヤーを追加したいので、ファイルシステム全体を誤ってコピーしていません。しかし、それを自由に削除してください。


0
 for item in `find A -type d | grep -E "\."` ; do cp -r $item B ; done
  • find A -type d A内にディレクトリのみの再帰リストを提供します
  • grep -E "\." ドットでディレクトリをフィルタリングします(つまり:非表示ディレクトリ)
  • -Eオプションが必要だったのは、それがなければ「現在のディレクトリ」も意味するからです。
  • バックスラッシュは、正規表現では「任意の文字」の意味を回避するためのものです
  • cp -r 再帰的にコピーする

私はAのファイルとフォルダーの構造を作成し、Git Bashでコマンドを実行しました(今はLinuxを使用していません)。


これは、ファイルの名前またはパスに空白または特殊文字が含まれている場合に機能しなくなります。
slhck 2014年

気づいてくれてありがとう:)実際、私は@gaboroncancioによる「テストケース」に限定しました。あなたが他のテストバッテリーを私に与えることができるなら、私はそれを改善しようとするかもしれません(もちろん、あなたが望むなら、この応答を編集するか、新しい答えを作成するかのどちらかで自分でそれを改善してください)
malarres

と呼ばれるフォルダに単純にドットファイルを置くとA B、に展開されるため、予期せず動作しcp -r A B/.dotfile Bます。一般的なアドバイスは、まったく解析findまたはls出力ないことです。を使用するfind場合は、フィルタリングではなく、独自のオプションを使用する必要があります。出力を他の場所にgrepパイプする場合はfind、を使用するか-print0、必要なコマンドを直接呼び出します。find マニュアルを参照してください。
slhck 2014年

さらに一般的には、他の回答で説明されているように、ファイルを操作するときはシェルグロブを使用するのが最も安全です(ただし、extglob設定が必要になることがよくあります)。
slhck 2014年

リンクをありがとう。それではfind解析を残しておきましょう。
マラール2014年

0

別の方法として、2番目の文字が英数字(source)の場合は、次のコマンドを使用できます。

cp -r A/.[a-zA-Z0-9]* B

これは質問で指定されたサンプルのファイル名とディレクトリ名で機能しますが、質問のテキストには「隠しファイルと隠しサブディレクトリ(ドットで始まるもの)」と書かれており、この回答では名前が次の名前で始まるファイルとディレクトリは見つかりませんドットと特殊文字。例:.@fooまたは..c
スコット

そのため、2番目の文字が英数字の場合に機能することを指摘します。;)
gaboroncancio 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.