309

In bash I need to do this:

  1. take all files in a directory

  2. copy them into an existing directory

How do I do this? I tried cp -r t1 t2 (both t1 and t2 are existing directories, t1 has files in it) but it created a directory called t1 inside t2, I don't want that, I need the files in t1 to go directly inside t2. How do I do this?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
David Chang
  • 3,091
  • 2
  • 15
  • 3
  • 13
    Why was this closed? It is arbitrary if a bash command is a built-in or external command (e.g. printf exists as both on most systems), so `cp` questions can well be seen as `bash` questions, which is a programming language. I have never seen a Python question talking about file copy be closed. – Ciro Santilli OurBigBook.com Jan 09 '14 at 10:38
  • Take a look at this https://stackoverflow.com/questions/23698183/how-to-force-cp-to-overwrite-directory-instead-of-creating-another-one-inside – theGiallo Apr 22 '17 at 15:53
  • I arrived in search of a reminder about the syntax of the Bash shell copy command, and I am happy to report that these commands seem also to work against the underlying NTFS filesystem on my Windows installation. – David A. Gray Nov 01 '18 at 16:44

10 Answers10

487

What you want is:

cp -R t1/. t2/

The dot at the end tells it to copy the contents of the current directory, not the directory itself. This method also includes hidden files and folders.

Doguhan Uluca
  • 6,933
  • 4
  • 38
  • 51
Nick
  • 10,904
  • 10
  • 49
  • 78
  • 4
    I really like this syntax, but for some reason it doesn't work with `mv`. Does anyone know why? – Martin von Wittich Sep 16 '13 at 11:18
  • 2
    Amazing. Where is this documented? Is it POSIX or extension? – Ciro Santilli OurBigBook.com Jan 09 '14 at 11:14
  • 12
    @CiroSantilli六四事件法轮功包卓轩 If you copy a directory, cp will create a directory and copy all the files into it. If you use the pretend folder called ".", which is the same as the directory holding it, the copy behaves this way. Let's say t1 contains a file called "file". cp will perform the operation equivalent to "cp t1/./file t2/./". It is copying the folder ".", but copying files into t2's "." folder strips the "./" because "t2/./" is the same as "t2/". Technically, this means it's POSIX built in behavior... but probably not in the way you might have been expecting! – striking Mar 12 '16 at 18:32
  • once I tested using the source path trailing a dot (t1/.) it copied the entire t1 folder with its content into the t2 folder. So I got a t1 folder inside the t2 folder. But once I used * instead of dot it did work and copied only the content of t1 into t2. So I think the best answer to this question is the following script -> cp -R t1/* t2/ – CodeMan Jul 29 '22 at 07:53
45
cp dir1/* dir2

Or if you have directories inside dir1 that you'd want to copy as well

cp -r dir1/* dir2
Bertrand Marron
  • 21,501
  • 8
  • 58
  • 94
  • 3
    Depending on how your shell is configured, you'll probably need to use "dir1/* dir1/.*" instead of "dir1/*" if you want to also catch hidden files. – ssokolow Sep 04 '10 at 20:17
  • 2
    Copying `dir1/.*` is not a good idea, as it copies dir1/.. (i.e. the parent of the directory you're actually trying to copy). It also copies dir1/. which is fine, except that it's already (mostly) been copied, so you're doing the work twice. – Gordon Davisson Sep 05 '10 at 18:37
  • 1
    You can get around the `dir1/.*`/hidden files problem by cd-ing into the directory you want to copy from, and then referring to it as `.`. So, if you want to copy all files including hidden files from a directory into an existing directory, you can: `cd [source dir]`, `cp . [path to destination dir, with no trailing slash]`. – RobW Apr 14 '12 at 18:17
36

If you want to copy something from one directory into the current directory, do this:

cp dir1/* .

This assumes you're not trying to copy hidden files.

Karl Giesing
  • 1,654
  • 3
  • 16
  • 24
8

Assuming t1 is the folder with files in it, and t2 is the empty directory. What you want is something like this:

sudo cp -R t1/* t2/

Bear in mind, for the first example, t1 and t2 have to be the full paths, or relative paths (based on where you are). If you want, you can navigate to the empty folder (t2) and do this:

sudo cp -R t1/* ./

Or you can navigate to the folder with files (t1) and do this:

sudo cp -R ./* t2/

Note: The * sign (or wildcard) stands for all files and folders. The -R flag means recursively (everything inside everything).

Konkret
  • 991
  • 9
  • 14
6
cp -R t1/ t2

The trailing slash on the source directory changes the semantics slightly, so it copies the contents but not the directory itself. It also avoids the problems with globbing and invisible files that Bertrand's answer has (copying t1/* misses invisible files, copying `t1/* t1/.*' copies t1/. and t1/.., which you don't want).

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
  • Your solution does not work, at least not on my installation (ubuntu 12.10) `$ mkdir t1` `$ mkdir t2` `$ touch t1/one` `$ touch t1/two` `$ touch t1/.three` `$ cp -R t1/ t2` `$ ls t2/` `t1` (sorry no codeformat in comments, readable version at http://pastebin.com/yszSxV6G) – zpon Feb 06 '13 at 07:32
  • Thank you for detailed explanation! – Volodymyr Kulyk Nov 04 '21 at 13:58
6

For inside some directory, this will be use full as it copy all contents from "folder1" to new directory "folder2" inside some directory.

$(pwd) will get path for current directory.

Notice the dot (.) after folder1 to get all contents inside folder1

cp -r $(pwd)/folder1/. $(pwd)/folder2
Bidyashish Kumar
  • 306
  • 4
  • 10
5

Nov, 2021 Update:

This code with Flag "-R" copies perfectly all the contents of "folder1" to existing "folder2":

cp -R folder1/. folder2

Flag "-R" copies symbolic links as well but Flag "-r" skips symbolic links so Flag "-R" is better than Flag "-r".

  • The latest GNU Grep 3.7:
-R, --dereference-recursive

For each directory operand, read and process all files in that directory, 
recursively, following all symbolic links.
-r, --recursive

For each directory operand, read and process all files in that directory, 
recursively. Follow symbolic links on the command line, but skip symlinks 
that are encountered recursively. Note that if no file operand is given, 
grep searches the working directory. This is the same as the 
‘--directories=recurse’ option.
sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
2

Depending on some details you might need to do something like this:

r=$(pwd)
case "$TARG" in
    /*) p=$r;;
    *) p="";;
    esac
cd "$SRC" && cp -r . "$p/$TARG"
cd "$r"

... this basically changes to the SRC directory and copies it to the target, then returns back to whence ever you started.

The extra fussing is to handle relative or absolute targets.

(This doesn't rely on subtle semantics of the cp command itself ... about how it handles source specifications with or without a trailing / ... since I'm not sure those are stable, portable, and reliable beyond just GNU cp and I don't know if they'll continue to be so in the future).

Jim Dennis
  • 17,054
  • 13
  • 68
  • 116
0

the correct option should be -T. used with -r to copy recursively.

$ cp -r -T t1 t2
yuanjianpeng
  • 335
  • 1
  • 9
0

In my case, on ubuntu 20.04.6, bash did not accept my double-quoted command. Eg.

cp "$HOME/.local/lib/*" ./lib/

returned =>

$>cp: cannot stat '/home/user1/.local/lib/*': No such file or directory

The directory exists on my system, so it's probably interpreting the star literally. By removing the quotes, it worked. Here is a reference page about bash quoted variable interpretation

pmg7670
  • 101
  • 5