40

I'm trying to copy files and subfolders from A folder without the A itself. For instance, A folder contains next:

| file1.txt   
| file2.txt    
| subfolder1   

Executing next command gives me wrong result:

sudo cp -r /home/username/A/ /usr/lib/B/

The result is

/usr/lib/B/A/...copied files...

instead of..

/usr/lib/B/...copied files...

How can I reach the expected one without origin-folder

67

advanced cp

cp -r /home/username/A/. /usr/lib/B/

This is especially great because it works no matter whether the target directory already exists.

shell globbing

If there are not too many objects in the directory then you can use shell globbing:

mkdir -p /usr/lib/B/
shopt -s dotglob
cp -r /home/username/A/* /usr/lib/B/

rsync

rsync -a /home/username/A/ /usr/lib/B/

The / at the end of the source path is important; works no matter whether the target directory already exists.

find

mkdir -p /usr/lib/B/
find /home/username/A/ -mindepth 1 -maxdepth 1 -exec cp -r -t /usr/lib/B/ {} +

or if you don't need empty subdirectories:

find /home/username/A/ -mindepth 1 -type f -exec cp --parents -t /usr/lib/B/ {} +

(without mkdir)

  • The first one works just fine! Any ideas why home/username/A/* (with star-symbol) doesn't make sense? Variant with dot at the end helped me, thanks! – pushandpop Jan 25 '15 at 15:05
  • @pushandpop A/* does make sense but there are situations in which it doesn't work. – Hauke Laging Jan 25 '15 at 16:01
  • 3
    shopt is bash specific. With zsh, use *(D). with ksh93, FIGNORE='@(.|..)'. cp -t is GNU specific. The find one will not work properly as it will copy both A/ and its content (including subdirs) several times. – Stéphane Chazelas Jan 25 '15 at 16:37
  • 1
    You also want -maxdepth 1 (-mindepth and -maxdepth being GNU extensions now also supported by a few others. Portably find .../. ! -name . -prune -exec ....) – Stéphane Chazelas Jan 25 '15 at 16:42
  • @StéphaneChazelas I guess there is a typo somewhere. find .../. causes an error here. – Hauke Laging Jan 25 '15 at 16:47
10

If on a GNU system, from man cp:

   -T, --no-target-directory
          treat DEST as a normal file

This allows you to write cp -rT /home/username/A/ /usr/lib/B/ to do exactly the right thing.

  • This should be the accepted answer, this is proper than shell globbing or using something else than cp. But that's true that -T won't work with a non-GNU cp. – noraj Nov 1 '18 at 17:07
3

Tell cp to copy the directory's contents and not the directory itself:

sudo cp -r /home/username/A/* /usr/lib/B/
  • Thanks! But it says: /usr/lib/B/ is not a directory – pushandpop Jan 25 '15 at 14:52
  • You will need to shopt -s dotglob for this to work if there are any dotfiles in /home/username/A/. – talkloud Jan 25 '15 at 14:52
  • 1
    @pushandpop well, yes. That's the target you had in your question so I assumed it was a directory. You need to create the target before attempting to copy files into it. – terdon Jan 25 '15 at 14:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.