1. 概要

cpコマンドと-Rオプションを使用して、ディレクトリを再帰的にコピーできることがわかっています。 このようにして、ソースディレクトリとその下のすべてのファイルが宛先にコピーされます。

ソースディレクトリからすべてのファイルをコピーしたくない場合があります。 代わりに、空のディレクトリ構造をターゲットディレクトリにコピーするだけです。

このチュートリアルでは、それを実現する方法について説明します。

2. 問題の紹介

問題を明確に理解するために、ディレクトリの例rootDirを見てみましょう。

$ tree -a rootDir 
rootDir
├── dir1
│   ├── 1_level.file
│   └── dir1_1
│       └── 1_1_level.file
├── dir2
│   └── 2_level.file
├── dir3
│   └── dir3_1
│       ├── 3_1_level.file
│       └── dir3_1_1
│           └── 3_1_1_level.file
└── root_level.file

6 directories, 6 files

rootDir ディレクトリには、さまざまなレベルのサブディレクトリがあります。 また、6つのファイルがディレクトリにあります。

私たちの目標は、 rootDir ディレクトリの空のディレクトリ構造を別の場所にコピーして、ターゲットディレクトリに次のようにすることです。

rootDir
├── dir1
│   └── dir1_1
├── dir2
└── dir3
    └── dir3_1
        └── dir3_1_1

問題を解決するための簡単なアイデアが浮かぶかもしれません。まず、 rootDir の下にあるすべてのものを再帰的にターゲットディレクトリにコピーしてから、すべてのファイルを削除します。

これで問題を解決できます。 ただし、ソースディレクトリに多数のファイルがある場合や大きなファイルが含まれている場合は、コピーに非常に長い時間がかかる可能性があります。 この問題に対するより効率的な解決策を探しています。

このチュートリアルでは、この問題を解決するための3つのアプローチについて説明します。

  • treeコマンドとxargsコマンドの使用
  • findコマンドの使用
  • rsyncコマンドの使用

次に、ディレクトリ構造をコピーする方法を詳しく見ていきましょう。

3. treeコマンドとxargsコマンドの使用

空のディレクトリ構造のクローンを作成する場合は、次の2つの手順で実行できます。

  1. 作成するすべてのディレクトリパスを取得する
  2. ディレクトリパスを入力として使用し、 mkdir-pを使用してこれらのディレクトリを作成します

次に、treeコマンドとxargsコマンドを使用して2つの手順を実行する方法を見てみましょう。

3.1. すべてのディレクトリパスを取得する

前のセクションで見たように、 tree コマンドは、ディレクトリ内のコンテンツをツリーのような形式で印刷できるため、非常に読みやすくなっています。

さらに、いくつかのオプションの組み合わせをコマンドに渡して、すべてのディレクトリパスを出力できます。

まず、 rootDir ディレクトリの親を入力し、その下にあるすべてのディレクトリパスを出力します。

$ tree -dfi --noreport rootDir
rootDir
rootDir/dir1
rootDir/dir1/dir1_1
rootDir/dir2
rootDir/dir3
rootDir/dir3/dir3_1
rootDir/dir3/dir3_1/dir3_1_1

次に、 tree コマンドに渡したオプションを確認し、それらの意味を理解しましょう。

  • -d treeコマンドにディレクトリのみを印刷するように依頼します
  • -f tree コマンドは、フルパスを出力します
  • -i :通常、treeはツリー形式で出力します。 つまり、出力では行が適切にインデントされます。 ただし、このオプションを使用すると、ツリーがインデント行を印刷できなくなります。
  • –noreport :このフラグは、「 xディレクトリ、yファイル」などの出力の最後にある要約レポートを抑制します。

3.2. ディレクトリの作成

これで、ソースディレクトリの下にすべてのディレクトリのパスがあります。 rootDir。 

次のステップは簡単です。各パスをmkdir-p コマンドに渡し、ターゲットディレクトリの下にそれらのディレクトリを作成します。

クローンを作成したいとしましょう rootDir 下の構造 / tmp/test。 それを行う方法を見てみましょう:

$ tree -dfi --noreport rootDir | xargs -I{} mkdir -p "/tmp/test/{}"

$ cd /tmp/test
$ tree -a rootDir 
rootDir
├── dir1
│   └── dir1_1
├── dir2
└── dir3
    └── dir3_1
        └── dir3_1_1

6 directories, 0 files

上記の例が示すように、treeコマンドの出力をxargsコマンドにパイプして、各ディレクトリパスをmkdirコマンドに渡します。

ソースrootDirディレクトリの親ディレクトリでこのコマンドを実行するため、“ / tmp / test” を、[によって読み取られる各パスのプレフィックスとして追加する必要があります。 X195X]xargsコマンド。

コマンドを実行した後、treeコマンドを再度使用して確認します。 ただし、今回は -aオプションを使用して、ファイルを含むすべてのコンテンツを印刷するようにtreeコマンドに指示します。

出力は、ファイルなしで / tmp /testの下にクリーンなrootDirディレクトリ構造を複製したことを示しています。 つまり、問題は解決しました。

4. findコマンドの使用

tree コマンドを使用して、ソースディレクトリの下のすべてのディレクトリパスを取得する方法を学びました。 同様に、findコマンドを使用してこれらのパスを取得することもできます。

$ find rootDir -type d
rootDir
rootDir/dir3
rootDir/dir3/dir3_1
rootDir/dir3/dir3_1/dir3_1_1
rootDir/dir1
rootDir/dir1/dir1_1
rootDir/dir2

tree 出力で行ったように、上記のfind出力をxargsコマンドにパイプして、ディレクトリを作成できます。

$ find rootDir -type d | xargs -I{} mkdir -p "/tmp/test/{}"

$ cd /tmp/test
$ tree -a rootDir 
rootDir
├── dir1
│   └── dir1_1
├── dir2
└── dir3
    └── dir3_1
        └── dir3_1_1

6 directories, 0 files

または、findコマンドの-exec引数を使用して、 mkdir-pコマンドを実行することもできます。

$ find rootDir -type d -exec mkdir -p "/tmp/test/{}" \;
$ cd /tmp/test
$ tree -a rootDir
rootDir
├── dir1
│   └── dir1_1
├── dir2
└── dir3
    └── dir3_1
        └── dir3_1_1

6 directories, 0 files

見つかった各ディレクトリパスは、mkdirコマンドのプレースホルダー「{}」を埋めます。 また、末尾の「\;」 必須です-execオプションのコマンド区切り文字です。

5. rsyncコマンドの使用

rsync コマンドは、強力なコマンドラインファイル同期およびコピーユーティリティです。

最後に、rsyncコマンドを使用してクリーンなディレクトリ構造を複製する方法を見てみましょう。

$ rsync -av -f"+ */" -f"- *" "/path/to/the/source/rootDir" "/tmp/test"
sending incremental file list
rootDir/
rootDir/dir1/
rootDir/dir1/dir1_1/
rootDir/dir2/
rootDir/dir3/
rootDir/dir3/dir3_1/
rootDir/dir3/dir3_1/dir3_1_1/

sent 258 bytes  received 44 bytes  604.00 bytes/sec
total size is 0  speedup is 0.00

$ cd /tmp/test
$ tree -a rootDir 
rootDir
├── dir1
│   └── dir1_1
├── dir2
└── dir3
    └── dir3_1
        └── dir3_1_1

6 directories, 0 files

rsyncコマンドに渡したオプションは少しわかりにくいように見えます。 次に、それらを簡単に見ていきましょう。

-a オプションは、rsyncに「アーカイブ」コピーを実行するように要求します。 つまり、コピーは再帰的に実行され、ファイルのアクセス許可は保持されます。 次に、-vオプションは冗長を意味します。 このオプションを使用すると、rsyncコマンドが実行した内容の詳細なログを確認できます。

次に、トリッキーな部分 -f” + * /” -f”-*”が来ます。

-fオプションは、 filter を定義し、フィルタールールはフィルターに従います。 rsync が機能すると、コピーするファイルにフィルターが適用されます。

プラスの「+」は「含める」を示し、マイナスの「-」は「除外する」を意味します。 このコマンドでは、すべてのディレクトリ“ + * /” を含めますが、すべてのファイル“-*”を除外します。 したがって、 rsync コマンドは、ソースディレクトリの下のディレクトリのみをコピーし、すべてのファイルをスキップします。

6. 結論

この記事では、ディレクトリ構造の下にファイルをコピーせずにディレクトリ構造を複製する方法について説明しました。

例を通して、それを達成するための3つの異なる方法を学びました。