497

宛先ディレクトリが存在しない場合に作成するコマンド (またはおそらく cp のオプション) が必要です。

例:

cp -? file /path/to/copy/file/to/is/very/deep/there
4

26 に答える 26

477
mkdir -p "$d" && cp file "$d"

( にはそのようなオプションはありませんcp)。

于 2009-10-07T06:58:54.250 に答える
288

次の両方に該当する場合:

  1. の GNU バージョンを使用しているcp(たとえば、Mac バージョンではない)、および
  2. 既存のディレクトリ構造からコピーしていて、再作成する必要があるだけです

--parentsのフラグを使用してこれを行うことができますcp。情報ページから ( http://www.gnu.org/software/coreutils/manual/html_node/cp-invocation.html#cp-invocationまたは または でinfo cp表示可能man cp):

--parents
     Form the name of each destination file by appending to the target
     directory a slash and the specified name of the source file.  The
     last argument given to `cp' must be the name of an existing
     directory.  For example, the command:

          cp --parents a/b/c existing_dir

     copies the file `a/b/c' to `existing_dir/a/b/c', creating any
     missing intermediate directories.

例:

/tmp $ mkdir foo
/tmp $ mkdir foo/foo
/tmp $ touch foo/foo/foo.txt
/tmp $ mkdir bar
/tmp $ cp --parents foo/foo/foo.txt bar
/tmp $ ls bar/foo/foo
foo.txt
于 2012-01-04T06:09:32.913 に答える
118

簡潔な答え

にコピーmyfile.txtするに/foo/bar/myfile.txtは、次を使用します。

mkdir -p /foo/bar && cp myfile.txt $_

これはどのように作動しますか?

これにはいくつかのコンポーネントがあるため、すべての構文を順を追って説明します。

mkdirユーティリティは、POSIX 標準で指定されているように、ディレクトリを作成します。ドキュメントによると、-p引数によりmkdir

不足している中間パス名コンポーネントを作成する

を呼び出すとmkdir -p /foo/barmkdirが作成さ/foo れ、 /foo/bar if/fooがまだ存在しないことを意味します。( がない-pと、代わりにエラーがスローされます。

&&リスト演算子は、POSIX標準(または必要に応じてBash マニュアルcp myfile.txt $_) に記載されているように、実行が成功した場合にのみ実行される効果がありmkdir -p /foo/barます。これは、失敗する可能性のある多くの理由のいずれかで失敗したcp場合、コマンドが実行を試みないことを意味します。mkdir

最後に、$_2 番目の引数として渡すcpは「特別なパラメーター」です。これは、変数に格納することなく、長い引数 (ファイル パスなど) の繰り返しを避けるのに便利です。Bash manualによると、次のようになります。

前のコマンドの最後の引数に展開します

この場合、それが/foo/barに渡したものmkdirです。したがって、cpコマンドは に展開され、新しく作成されたディレクトリcp myfile.txt /foo/barにコピーされます。myfile.txt/foo/bar

は POSIX 標準の一部で$_ないため、理論的には、Unix バリアントには、この構造をサポートしないシェルが含まれている可能性があります。ただし、サポートしていない最新のシェルは知りません$_。確かに、Bash、Dash、および zsh はすべてそうです。


最後の注意: この回答の冒頭で指定したコマンドは、ディレクトリ名にスペースが含まれていないことを前提としています。スペースを含む名前を扱う場合は、それらを引用符で囲んで別の単語mkdirまたはに対する別の引数として扱われませんcp。したがって、コマンドは実際には次のようになります。

mkdir -p "/my directory/name with/spaces" && cp "my filename with spaces.txt" "$_"
于 2015-09-15T22:40:07.243 に答える
50

このような古い質問ですが、別の解決策を提案できるかもしれません。

プログラムを使用しinstallてファイルをコピーし、「その場で」宛先パスを作成できます。

install -D file /path/to/copy/file/to/is/very/deep/there/file

ただし、考慮すべき点がいくつかあります。

  1. 宛先パスだけでなく、宛先ファイル名も指定する必要があります
  2. 宛先ファイルは実行可能になります(少なくとも、テストから見た限り)

-m宛先ファイルにアクセス許可を設定するオプションを追加することで、#2 を簡単に修正できます (例:で新しいファイルを作成するのと同じように、-m 664アクセス許可で宛先ファイルを作成します)。rw-rw-r--touch


そして、ここに私が触発された答えへの恥知らずなリンクがあります=)

于 2015-04-07T10:11:35.973 に答える
23

ファイルが存在するための穴を掘るので、それを「埋める」コピーと呼んで、あなたが望むことをするシェル関数:

bury_copy() { mkdir -p `dirname $2` && cp "$1" "$2"; }
于 2009-10-07T22:04:07.017 に答える
13

これを行う1つの方法は次のとおりです。

mkdir -p `dirname /path/to/copy/file/to/is/very/deep/there` \
   && cp -r file /path/to/copy/file/to/is/very/deep/there

dirname宛先ディレクトリまたはファイルの親を提供します。mkdir -p `dirname ...` はそのディレクトリを作成し、 cp -r を呼び出すときに正しいベース ディレクトリが配置されるようにします。

--parents に対するこの利点は、宛先パスの最後の要素がファイル名である場合に機能することです。

また、OS X でも動作します。

于 2014-02-09T15:23:51.853 に答える
5

以下を .bashrc に追加するだけで、必要に応じて調整できます。Ubuntu で動作します。

mkcp() {
    test -d "$2" || mkdir -p "$2"
    cp -r "$1" "$2"
}

たとえば、「test」ファイルを宛先ディレクトリ「d」にコピーする場合は、

mkcp test a/b/c/d

mkcpは、最初に宛先ディレクトリが存在するかどうかを確認し、存在しない場合は作成してソース ファイル/ディレクトリをコピーします。

于 2016-01-05T09:26:25.500 に答える
0
rsync file /path/to/copy/file/to/is/very/deep/there

適切な種類のrsync.

于 2015-11-02T21:32:46.617 に答える
0

これは、MacOS 上の GNU /bin/bash バージョン 3.2 で動作します (Catalina と Big Sur の両方でテスト済み)。

cp -Rv <existing-source-folder>/   <non-existing-2becreated-destination-folder>

「v」オプションは冗長用です。

そして、「-R」オプションは「再帰的」と考えています。

男性の -R の完全な説明は次のとおりです。

source_file がディレクトリを指定する場合、cp はそのディレクトリとその時点で接続されているサブツリー全体をコピーします。source_file が / で終わる場合、ディレクトリ自体ではなく、ディレクトリの内容がコピーされます。このオプションはまた、シンボリック リンクを間接的にではなくコピーし、cp が通常のファイルとしてコピーするのではなく特別なファイルを作成するようにします。作成されたディレクトリは、対応するソース ディレクトリと同じモードになり、プロセスの umask によって変更されません。

-R モードでは、エラーが検出されても cp はコピーを続行します。

cp は、ハードリンクされたファイルを別のファイルとしてコピーすることに注意してください。ハード リンクを保持する必要がある場合は、代わりに tar(1)、cpio(1)、または pax(1) の使用を検討してください。

以下の例では、existingfolder のすべての内容 (フォルダー自体ではなく) を newfolder にコピーするために、existingfolder の末尾に「/」を使用しています。

cp -Rv existingfolder/  newfolder

それを試してみてください。

于 2021-07-01T02:01:06.933 に答える
0

findで使用できますPerl。コマンドは次のようになります。

find file | perl -lne '$t = "/path/to/copy/file/to/is/very/deep/there/"; /^(.+)\/.+$/; `mkdir -p $t$1` unless(-d "$t$1"); `cp $_ $t$_` unless(-f "$t$_");'

このコマンドは、ディレクトリ$tが存在しない場合は作成します。そして、内部に存在しない限りのみにコピーfileします。$tfile$t

于 2021-01-24T07:30:38.983 に答える
-1

あなたが次のようなことをしているとしましょう

cp file1.txt A/B/C/D/file.txt

A/B/C/D はまだ存在しないディレクトリです

可能な解決策は次のとおりです

DIR=$(dirname A/B/C/D/file.txt)
# DIR= "A/B/C/D"
mkdir -p $DIR
cp file1.txt A/B/C/D/file.txt

それが役立つことを願っています!

于 2017-02-28T22:36:58.880 に答える