Copy a file and auto create folders structure

2 minute read  

How to copy a file and auto create all the intermediate folders leading to it?. We can use the command cp --parents.

Assuming we have this:

d1
├── d11
│   └── d111
│       └── f1.txt
└── d12

We can copy f1.txt and create all the folders leading to f1 which are d1/d11/d111 with:

$ cp --parents d1/d11/d111/f1.txt destinationFolder

# We'll then have
destinationFolder
└── d1
    └── d11
        └── d111
            └── f1.txt

MacOS comes with a BSD version of cp which doesn’t have the --parents flag. We need to get GNU cp which is bundled in the coreutils package.

GET GNU cp

On Mac, get coreutils package with homebrew:

$ brew install coreutils

Maker sure our PATH is set properly in .bashrc or .bash_profile for these GNU utilities:

export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH"
export MANPATH="/usr/local/opt/coreutils/libexec/gnuman:$MANPATH"

Our cp should now be the GNU version:

$ cp --version
cp (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.

USE cp --parents

Demo folder for illustration

# Make a demo folder
$ mkdir demo-cp
$ cd demo-cp/

# Make nesting folders & create a file
$ mkdir -p d1/d11/d111 d1/d12
$ touch d1/d11/d111/f1.txt

# Make destination folder
$ mkdir dest

# We'll then have this
demo-cp
├── d1
│   ├── d11
│   │   └── d111
│   │       └── f1.txt
│   └── d12
└── dest
5 directories, 1 file

Copy f1.txt and all the intermediate folders

# Copy f1.txt and auto create d1/d11/d111 intermediate folders under dest
$ cp --parents d1/d11/d111/f1.txt dest

# Note that the full path d1/d11/d111/f1.txt has been created/copied under dest
demo-cp
├── d1
│   ├── d11
│   │   └── d111
│   │       └── f1.txt
│   └── d12
└── dest
    └── d1
        └── d11
            └── d111
                └── f1.txt
8 directories, 2 files

cp --parents is different than cp -r

cp -r or cp -R is to copy directories recursively. If we were to copy folder d1 recursively with cp -r, it will copy everything under d1, whereas cp --parents only copies the single path to f1.txt.

# Copy d1 recursively to dest
$ cp -r d1 dest

# Note that we have copied the entire folder d1, including the empty folder d12
demo-cp
├── d1
│   ├── d11
│   │   └── d111
│   │       └── f1.txt
│   └── d12
└── dest
    └── d1
        ├── d11
        │   └── d111
        │       └── f1.txt
        └── d12
9 directories, 2 files

Tags:

Published:

Leave a Comment