cpを使用してべき等な方法でフォルダを再帰的にコピーするにはどうすればよいですか?
On 12月 1, 2020 by admin使用すると
cp -R inputFolder outputFolder
結果はコンテキスト依存:
-
outputFolder
が存在しない場合は、作成され、複製されたフォルダーパスはoutputFolder
になります。 -
outputFolder
が存在する場合、作成されたクローンはbeoutputFolder/inputFolder
これはひどいです、インストールスクリプトを作成したいので、ユーザーが誤って2回実行した場合、最初にoutputFolder
が作成され、2回目の実行ですべてのものが作成されます。 outputFolder/inputFolder
でもう一度作成します。
- 常に最初の動作が必要です:クローンを作成しますオリジナルの横(兄弟として)。
-
cp
を使用してポータブルにしたい(例: MINGWはしませんrsync
が出荷されました) -
cp -R --parents
を確認しましたが、これにより、ディレクトリツリーの最後までパスが再作成されます(クローンはoutputFolder
ではなく、some/path/outputFolder
) -
--remove-destination
になります。または--update
2が何も変更しない場合でも、outputFolder/inputFolder
にコピーされます。最初にoutputFolder
の存在を確認せずに(フォルダが存在しない場合は…)、またはrm -rf outputFolder
を使用せずに、これを行う方法があります。 ?
これを行うための合意されたポータブルUNIXの方法は何ですか?
コメント
回答
代わりにこれを使用してください:
cp -R inputFolder/. outputFolder
これは、たとえばcp -R aaa/bbb ccc
が機能するのとまったく同じように機能します。ccc
が存在しない場合は「それ」です。 ■bbb
とその内容のコピーとして作成されたもの。ただし、ccc
がすでに存在する場合、ccc/bbb
はbbb
とその内容のコピーとして作成されます。 。
bbb
のほとんどすべてのインスタンスで、これにより、質問で指摘した望ましくない動作が発生します。ただし、この特定の状況では、bbb
は.
であるため、aaa/bbb
は実際にはaaa/.
、これは実際にはaaa
ですが、別の名前です。したがって、次の2つのシナリオがあります。
-
ccc
は存在しません:コマンド
cp -R aaa/. ccc
は、「ccc
を作成し、aaa/.
の内容をccc/.
、つまりaaa
をccc
にコピーします。 -
ccc
は存在します:コマンド
cp -R aaa/. ccc
は、「aaa/.
の内容をにコピーすることを意味しますccc/.
、つまりaaa
をccc
にコピーします。
コメント
- ええと、'は私にとっては新しいものですが、機能しているようです。これはどこかに文書化されていますか?
- 'は
inputFolder
をテストしました。
そして確かにそれはWindows / GitBashで私のために働きます。 (ただし、末尾の/
だけでは機能しません。スラッシュの後のドットも必要です)。'面白いので、+ 1を付けましたが、'は、公開コードで使用するには少しトリッキーすぎるでしょう:)
回答
フォルダをコピーせず、内容のみをコピーします。
## Create the target directory. The -p suppresses error messages ## if the directory already exists mkdir -p outputFolder ## Copy the contents recursively, this will not recreate the parent cp -R inputfolder/* outputfolder/
このようにして、スクリプトの最初の実行時にターゲットディレクトリが作成されるようにし、
Chris Downは、bashでは、名前が.
で始まるファイルをスキップすることを非常に正確に指摘しています。これを回避するには、上記のコマンドを実行する前に、shopt -s dotglob
を実行できます。
両方 -p
の場合は
、ividの場合は -R
= “a7c675a4a9″>
はPOSIXによって定義されているため、完全に移植可能である必要があります。
コメント
- 注:これは、
.
で始まるファイルを'コピーしません。 bashでは、そのためにdotglob
を使用できます。 - 入力フォルダー内のディレクトリエントリの数が多い場合、globの拡張により、このメソッドは失敗する可能性があります。コマンドラインの最大長を超える可能性があります。
回答
-T
オプションをcp
に追加します。これはGNUcoreutils cp
バージョン8.22に存在します。それ以外では移植できない可能性があります。
コメント
- ええ、これはまさに私が望んでいたことのようです:
cp -T
(cp --no-target-directory
)。 unix.stackexchange.com/questions/94831/ … 残念ながら私のバージョンのcp
ははるかに古いです。 - +1今日これを使用しました。
-u
は、怠惰にするために追加するのに最適なオプションです。
回答
rsync
を使用することもできます:
rsync -uav inputFolder/ outputFolder/
(特に最初のスラッシュの後のスラッシュに注意してください) )
回答
iv id = “の-t
オプションを使用できますa7c675a4a9 “>
コマンド:
cp -R inputFolder -t outputFolder
ターゲットフォルダが存在しない場合、エラーがスローされます:
cp: failed to access ‘outputFolder’: No such file or directory
上記のコマンドは、必要に応じてinputFolder
をそのコンテンツ(コンテンツだけでなく)とともにコピーします
inputFolder
の内容だけをコピーするには、少し注意が必要です(アスタリスクを使用しているときにシェルグロブを使用する場合は注意が必要です*)
cp -R -t outputFolder/ -- inputFolder/*
ターゲットフォルダが存在しない場合、エラーがスローされます:
cp: failed to access ‘outputFolder’: No such file or directory
cp (GNU coreutils) 8.23
回答
私の意見では、rm -rf outputFolder
ほどシンプルで移植性の高いものはありません。だから、私はいつもそれに固執します。あなたの質問が異なることは理解していますが、これがベストプラクティスだと思います。
コメント
- 特定の権限または所有権がある場合は失敗します維持する必要のあるターゲットに。または、シンボリックリンクの場合。
- この質問では、ディレクトリが存在しない場合と存在する場合の両方で、
cp
の結果を同じにする必要があります。では、何について話しているのですか? - OPによって提供される
cp
コマンドは、権限を保持しません' (またはタイムスタンプ)。
mv
がファイルのコレクションを単一の通常のファイルに移動しないようにする方法rsync
を使用してみませんか?cp
を使用する必要があります。2つのtar
コマンド間のパイプは、ツリーをコピーするための信頼できる優れた方法です。rsync
が出荷されていないMINGWでこれを機能させたい。tar -C input -cf - . | tar -C output -xf -
は機能します。-C
は作業ディレクトリを変更しますが、これは標準オプションではないため、'がサポートされていない場合は、で2つのtarを実行する必要があります。そもそも適切な作業ディレクトリ、例えば( cd input && tar -cf - . ) | ( cd output && tar -xf - )
ただし、' Windowsを扱っている場合は、roaima 'の回答を使用します。 。