Linux copy folder with subfolders

How can I copy the contents of a folder to another folder in a different directory using terminal?

I am trying to copy the contents of a folder to another folder in a different directory using terminal. Would somebody be able to provide me an example of the command line syntax required to achieve this?

8 Answers 8

You can copy the content of a folder /source to another existing folder /dest with the command

The -a option is an improved recursive option, that preserve all file attributes, and also preserve symlinks.

The . at end of the source path is a specific cp syntax that allow to copy all files and folders, included hidden ones.

@DylanValade: -a already implies —preserve=all , that is wider than -p = —preserve=mode,ownership,timestamps .

@BennyNeugebauer: scp is used to copy over a network (through ssh ) and only encrypts the communication channel, not the files on the destination filesystem.

«The . at end of the source path is a specific cp syntax that allow to copy all files and folders, included hidden ones.», this is not related to cp, but related to bash. The dot means «this location» and avoids the use of bash globbing, where by default files/directories starting with a . are not expanded.

Can someone explain the need behind use of mypath/. instead of the existing bash wildcard expansion character, mypath/* ?

rsync -a source/ destination 

The advantages of rsync are:

  1. After the initial sync, it will then copy only the files that have changed.
  2. You can use it over a network, convenient for files in $HOME, especially config files.

This will not copy hidden files, since bash expands * only to non-hidden file. The solution by @Joschua is safer.

If it’s a big folder you may wish to use one of these options to view progress while it’s copying askubuntu.com/questions/609303/…

Lets say you have a folder called folder1 in your ~ , inside folder1 is 1 file called file1 and 2 folders called sub1 and sub2 each with other files and folders inside them.

To copy all the contents of ~/folder1 to ~/new_folder1 you would use

new_folder1 would then contain all the files and folders from folder1 .

cp is the command to copy using a terminal, -r makes it recursively (so, current directory + further directories inside current) ~/folder1 is the origin folder, ~/new_folder1 is the destination folder for the files/folders inside the origin.

Thank you Bruno! It helped me to understand the syntax, though I had to change it a bit(removing ~ sign). Maybe because the destination folder was in /opt, which resides in another file system. And thank you Portablejim to remember the hidden file thing!

Читайте также:  Useradd in linux with password

The trailing period is important. Without it, sometimes it may create a new subdirectory ~/new_folder1/folder1 instead of copying the contents over.

@Alex78191 [root@ home]# mkdir food [root@ home]# cd food/ [root@ food]# mkdir .fruit [root@ food]# mkdir veggies [root@ food]# touch veggies/carrots [root@ food]# touch .fruit/apple [root@ food]# ls * carrots [root@ food]#

Simple example.

Copy the directory dir_1 and its contents (files) into directory dir_2:

cp -r ./dir_1 ./dir_2 # or cp -r ./dir_1/ ./dir_2/ # Results in: ./dir_2/dir_1/_files_ 

Copy only the contents (files) of dir_1 into directory dir_2:

cp -r ./dir_1/. ./dir_2 # or cp -r ./dir_1/. ./dir_2/ # Results in: ./dir_2/_files_ 

_files_ is a placeholder for the actual files located in the directory.

Check this http://www.cyberciti.biz/faq/copy-folder-linux-command-line/ for more information on copying folder. Hope this helps.

cp is a Linux command for copying files and directories. The syntax is as follows:

cp source destination cp dir1 dir2 cp -option source destination cp -option1 -option2 source destination 

In this example copy /home/vivek/letters folder and all its files to /usb/backup directory:

cp -avr /home/vivek/letters /usb/backup 

-a : Preserve the specified attributes such as directory an file mode, ownership, timestamps, if possible additional attributes: context, links, xattr, all.

-v : Explain what is being done.

-r : Copy directories recursively. Example

Copy a folder called /tmp/conf to /tmp/backup:

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

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

-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. 

Источник

Команда cp: правильное копирование папок с файлами в *nix

В этой статье будут раскрыты некоторые неочевидные вещи связанные с использованием wildcards при копировании, неоднозначное поведение команды cp при копировании, а также способы позволяющие корректно копировать огромное количество файлов без пропусков и вылетов.

Допустим нам нужно скопировать всё из папки /source в папку /target.

Первое, что приходит на ум это:

Сразу исправим эту команду на:

Ключ -a добавит копирование всех аттрибутов, прав и добавит рекурсию. Когда не требуется точное воспроизведение прав достаточно ключа -r .

Читайте также:  Открыть конфигурационный файл linux

После копирования мы обнаружим, что скопировались не все файлы — были проигнорированы файлы начинающиеся с точки типа:

.profile
.local
.mc
и тому подобные.

Потому что wildcards обрабатывает shell ( bash в типовом случае). По умолчанию bash проигнорирует все файлы начинающиеся с точек, так как трактует их как скрытые. Чтобы избежать такого поведения нам придётся изменить поведение bash с помощью команды:

Чтобы это изменение поведения сохранилось после перезагрузки, можно сделать файл wildcard.sh c этой командой в папке /etc/profile.d (возможно в вашем дистрибутиве иная папка).

А если в директории-источнике нет файлов, то shell не сможет ничего подставить вместо звёздочки, и также копирование завершится с ошибкой. Против подобной ситуации есть опции failglob и nullglob . Нам потребуется выставить failglob , которая не даст команде выполниться. nullglob не подойдёт, так как она строку с wildcards не нашедшими совпадения преобразует в пустую строку (нулевой длины), что для cp вызовет ошибку.

Однако, если в папке тысячи файлов и больше, то от подхода с использованием wildcards стоит отказаться вовсе. Дело в том, что bash разворачивает wildcards в очень длинную командную строку наподобие:

cp -a /souce/a /source/b /source/c …… /target

На длину командной строки есть ограничение, которое мы можем узнать используя команду:

Получим максимальную длину командной строки в байтах:

…. Maximum length of command we could actually use: 2089314 ….

Итак, давайте будем обходиться вовсе без wildcards.

И тут мы столкнёмся с неоднозначностью поведения cp . Если папки /target не существует, то мы получим то, что нам нужно.

Однако, если папка target существует, то файлы будут скопированы в папку /target/source.

Не всегда мы можем удалить заранее папку /target, так как в ней могут быть нужные нам файлы и наша цель, допустим, дополнить файлы в /target файлами из /source.

Если бы папки источника и приёмника назывались одинаково, например, мы копировали бы из /source в /home/source, то можно было бы использовать команду:

И после копирования файлы в /home/source оказались бы дополненными файлами из /source.

Такая вот логическая задачка: мы можем дополнить файлы в директории-приёмнике, если папки называются одинаково, но если они отличаются, то папка-исходник будет помещена внутрь приёмника. Как скопировать файлы из /source в /target с помощью cp без wildcards?

Чтобы обойти это вредное ограничение мы используем неочевидное решение:

Те кто хорошо знаком с DOS и Linux уже всё поняли: внутри каждой папки есть 2 невидимые папки «.» и «..», являющиеся псевдопапками-ссылками на текущую и вышестоящие директории.

  • При копировании cp проверяет существование и пытается создать /target/.
  • Такая директория существует и это есть /target
  • Файлы из /source скопированы в /target корректно.

Поведение этой команды однозначно. Всё отработает без ошибок вне зависимости от того миллион у вас файлов или их нет вовсе.

Читайте также:  Linux ftp list all files

Выводы

Если нужно скопировать все файлы из одной папки в другую, не используем wildcards, вместо них лучше использовать cp в сочетании с точкой в конце папки-источника. Это скопирует все файлы, включая скрытые и не завалится при миллионах файлов или полном отсутствии файлов.

Послесловие

vmspike предложил аналогичный по результату вариант команды:

ВНИМАНИЕ: регистр буквы T имеет значение. Если перепутать, то получите полную белиберду: направление копирования поменяется.
Благодарности:

  • Компании RUVDS.COM за поддержку и возможность публикации в своем блоге на Хабре.
  • За изображение TripletConcept. Картинка очень большая и детальная, можно открыть в отдельном окне.

Источник

Copying specific subfolders with directory structure to a new folder

I want to copy all the subdirectories ( Subdir1 , Subdir2 , Subdir3 ) to a new folder. But I only want to copy fo1 and fo2 folders in the new place. Not sure how could it be done.

4 Answers 4

If the tree of directories is more than just . /f03 you can use this rsync command to copy every fo1 & fo2 and exclude every other directory with the name fo* .

$ rsync -avz --include='fo[12]/' --exclude='fo*/' \ Main_Dir/ new_Main_Dir/. 

When dealing with these types of copy scenarios I always make use of rsync and it’s —dry-run & —verbose switches so I can see what it’s going to do without actually having to copy the files.

$ rsync -avz --dry-run --verbose --include='fo[12]/' --exclude='fo*/' \ Main_Dir/ new_Main_Dir/. 

Example

$ rsync -avz --dry-run --include='fo[12]/' --exclude='fo*/' \ Main_Dir/ new_Main_Dir/. sending incremental file list ./ Subdir1/ Subdir1/fo1/ Subdir1/fo2/ Subdir2/ Subdir2/fo1/ Subdir2/fo2/ Subdir3/ Subdir3/fo1/ Subdir3/fo2/ sent 201 bytes received 51 bytes 504.00 bytes/sec total size is 0 speedup is 0.00 (DRY RUN) 

If you want to see some of rsync ‘s internal logic as to what is being included/excluded then make use of the —verbose switch.

$ rsync -avz --dry-run --verbose --include='fo[12]/' --exclude='fo*/' \ Main_Dir/ new_Main_Dir/. sending incremental file list [sender] showing directory Subdir1/fo2 because of pattern fo[12]/ [sender] showing directory Subdir1/fo1 because of pattern fo[12]/ [sender] hiding directory Subdir1/fo3 because of pattern fo*/ [sender] showing directory Subdir2/fo2 because of pattern fo[12]/ [sender] showing directory Subdir2/fo1 because of pattern fo[12]/ [sender] hiding directory Subdir2/fo3 because of pattern fo*/ [sender] showing directory Subdir3/fo2 because of pattern fo[12]/ [sender] showing directory Subdir3/fo1 because of pattern fo[12]/ [sender] hiding directory Subdir3/fo3 because of pattern fo*/ delta-transmission disabled for local transfer or --whole-file ./ Subdir1/ Subdir1/fo1/ Subdir1/fo2/ Subdir2/ Subdir2/fo1/ Subdir2/fo2/ Subdir3/ Subdir3/fo1/ Subdir3/fo2/ total: matches=0 hash_hits=0 false_alarms=0 data=0 sent 201 bytes received 51 bytes 504.00 bytes/sec total size is 0 speedup is 0.00 (DRY RUN) 

If you need to exclude other forms of directories you can add multiple excludes.

Источник

Оцените статью
Adblock
detector