Я хотел бы скопировать содержимое каталога 1 в каталог 2. Однако я хотел бы копировать только файлы (а не каталоги) из моего каталога 1. Как я могу это сделать?
cp dir1/* dir2/*
тогда у меня все еще есть проблема с каталогами.
Кроме того, все мои файлы не имеют расширения, поэтому . не добьется цели
cp dir1/* dir2
илиcp -t dir2 dir1/*
Ответы:
cp
не будет копировать каталоги, если это явно не указано (--recursive
например, см.man cp
).Примечание 1:
cp
скорее всего, выйдет с ненулевым статусом, но файлы все равно будут скопированы. Это может быть проблемой , когда цепочки команд на основе кодов выхода:&&
,||
,if cp -r dir1/* dir2; then ...
и т.д. (спасибо contrebis за свой комментарий по этому вопросу )Примечание 2 :
cp
ожидается, что последним параметром будет одно имя файла или каталога.*
После имени целевого каталога действительно не должно быть подстановочных знаков .dir2\*
будет расширяться оболочкой так же, какdir1\*
. Неожиданные вещи будут происходить:dir2
пусто и зависит от вашей оболочки и настроек:dir2/*
будет восприниматься буквально (поиск файла / каталога с именем*
), что, вероятно, также приведет к ошибке, если она*
не существует.dir2/*
он просто будет удален из команды полностью, оставивcp dir1/*
. Который, в зависимости от расширенияdir1/*
, может даже уничтожить данные:dir1/*
соответствует только один файл или каталог, вы получите сообщение об ошибкеcp
.dir1/*
совпадает ровно два файла, один будет перезаписан другим ( Плохо ).dir/*
совпадает несколько файлов, а последнее совпадение равно a, вы получите сообщение об ошибке.dir/*
является каталогом, все остальные совпадения будут перемещены в него.dir2
не пусто, это опять зависит:dir2/*
является каталогом,dir1/*
а другие совпаденияdir2/*
будут перемещены в.dir2/*
является файл, вы, вероятно, получите сообщение об ошибке, если неdir1/*
соответствует только один файл.источник
$ cp dir1/* dir2
->cp: dir1/isadir is a directory (not copied).
Выход со статусом 1 для меня.cp
случае копируются ли файлы, совпадающиеdir1/*
на каждой проверенной мной системе: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 и 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 и 10 (гдеcp
фактически завершается с кодом 2). Таким образом, это поведение не является новым (SuSE 8.1 с 2002 года) и не ограничивается Linux.cp
выходит с ненулевым кодом выхода, потому что он не может сделать все, что ему было сказано. Это не значит, что ничего не делает .&&
этим, это может вызвать проблемы. Я пытался что-то вроде этого, хотя я не могу вспомнить контекст сейчас.*
скрытых файлов или включение скрытых файлов зависит от оболочки. Если*
не содержит скрытых файлов, вы можете сопоставить их с.*
. Обратите внимание , что это будет включать в себя.
и..
наbash
и ,dash
но не наzsh
. В контексте этого ответа вы можете сойти с рук,cp dir1/* dir1/.* dir2
потому что.
и..
каталоги и не будут скопированы.zsh
также можно включить скрытые файлы с*(D)
.Это оболочка, которая расширяет символы подстановки, а не команды. Итак,
cp dir1/* dir2/*
сначала расширяются два подстановочных знака, а затем вызываетсяcp
результат. Это совсем не то, что вы, очевидно, ожидаете: в зависимости от того, сколько файлов уже естьdir2
,dir2/*
может быть расширен до одного или нескольких аргументов. Командаcp
не знает, какие из ее аргументов были получены при расширении первого шаблона, а какие - при расширении второго шаблона. Ожидается, что его последним аргументом будет имя каталога назначения. Таким образом, чтобы скопировать все файлы из каталогаdir1
в каталогdir2
, последний аргумент должен быть каталогомdir2
:Так как
*
совпадает со всеми файлами,cp
пытается скопировать все файлы. Это включает в себя каталоги: каталоги тоже файлы. Он пропускает каталоги, но сообщает об ошибке. Он копирует содержимое специальных файлов, таких как именованные каналы (что-то лучше записывать в них, или ониcp
будут блокироваться) и т. Д.Чтобы копировать только обычные файлы, вам нужно ограничить соответствие. В zsh вы можете использовать для этого квалификатор glob
.
:У других оболочек этого нет. Вы можете использовать
find
команду для фильтрации по типам файлов. Предполагая, что вы используете не встроенный Linux или Cygwin:В Linux, FreeBSD и OSX:
источник
-maxdepth 1
. Кроме того, есть ли способ рекурсивного копирования и сохранения исходной иерархии каталогов в целевом каталоге?-maxdepth 1
,find
команда превратилась бы в подкаталоги, чего здесь не хотелось. Если вы хотите скопировать все дерево каталогов , включая подкаталоги, это совершенно другой вопрос, и ответ на него намного проще:cp -a dir1 dir2
.Ниже приведена команда для копирования файла из исходного каталога в целевой.
Перейдите в исходную папку и напишите ниже команду:
$ cp fileName destination directory path
Пример:
источник