Как скопировать файл в несколько папок с помощью командной строки?

68

Я попытался скопировать файл test.txtв несколько каталогов с помощью одной команды:

cp ~/test.txt ~/folder1 ~/folder2

Но мне не удалось. Есть ли способ сделать это в одной команде, чтобы я мог скопировать файл или даже папку в несколько каталогов?

Nux
источник
Не легко. Возможно, вы захотите заглянуть в «rsync» для эффективного обновления нескольких существующих копий папки
Thorbjørn Ravn Andersen
3
Попробуйте немного изучить bash-скрипт. Это может быть очень полезно:for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
Шахбаз
Не единственная команда, но может просто помочь некоторым людям, которые наткнулись здесь:cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
Ману Ярвинен
Дубликат stackoverflow.com/a/195972/2097284 .
Камиль Гудесюн

Ответы:

72

cpможет копировать из нескольких источников, но не может копировать в несколько мест назначения. Смотрите man cpдля получения дополнительной информации.

Я знаю только одну команду bash, которая может копировать / сохранять в нескольких местах назначения tee.

Вы можете использовать его в вашем случае следующим образом:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt

Обратите внимание, что teeтакже записывает ввод в стандартный вывод (stdout). Так что если вы не хотите этого, вы можете предотвратить это, перенаправив стандартный вывод /dev/nullследующим образом:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null
Раду Рэдяну
источник
10
Умно, это обман! :)
Тердон
5
+1, умный! И если вы используете >/dev/nullработы с бинарными файлами, не
портя
1
+1 для тебя, твой всегда ма человек :), но что если я захочу скопировать каталог?
nux
2
@nux Не забывайте использовать -rопцию cpв случае каталогов
Radu Rădeanu
4
@nux: в teeотличие от cpкопирует только содержимое файла, игнорируя его режим, владельца, метки времени. Чтобы не повторять имя файла:f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
jfs
61

Другой способ получить копию в нескольких местах - следующая команда:

find dir1 dir2 -exec cp file.txt {} \;

Если у dir1 или dir2 есть подкаталоги, в которые вы не хотите копировать файл, добавьте -maxdepth 0опцию:

find dir1 dir2 -maxdepth 0 -exec cp file.txt {} \;

Обратите внимание, что это перезапишет каждый файл с содержимым dir1и dir2вместе file.txtс ним, в дополнение к копированию. Чтобы копировать только, file.txtне затрагивая другие файлы в этих каталогах, попросите findдействовать только в каталогах:

find dir1 dir2 -type d -exec cp file.txt {} \;
Сильвен Пино
источник
4
Отличное решение! Кажется мне более совершенным, чем с тройником.
Данатела
1
Действительно, перенаправление не используется, и это все еще одна команда.
Сильвен Пино
2
@SylvainPineau На самом деле их 3: один findи два раза (в данном случае) cp. Не скажу, что findнужно много времени.
Раду Рэдяну
3
Если определение «команда» является вызовом «exec», возможно, но это «одна команда» в моей книге.
Кодзиро
2
Я продолжаю возвращаться к этому, поэтому подумал, что должен дать голос: D
Джонатан
31

Команда

cp ~/test.txt ~/folder1 ~/folder2

пытается скопировать два файла ( ~/test.txtи ~/folder1) в место назначения folder2. (И если он ~/folder2существует и является каталогом, у вас будет предупреждение "Пропуск каталога").

Если вы хотите сделать несколько копий файла test.txt, вы должны использовать цикл или несколько команд ...

for i in ~/folder1 ~/folder2; do cp  ~/test.txt $i; done 

(... и будьте осторожны, если в именах файлов есть пробелы, вам нужно будет заключить в кавычки).

Чтобы скопировать целые каталоги, вы должны использовать -rопцию:

for i in ~/folder1 ~/folder2; do cp -r ~/folder3 $i; done

это создаст ~/folder1/folder3и ~/folder2/folder3со всеми включенными файлами.

Rmano
источник
1
Для проходящего читателя: согласно спецификации цикл for является составной командой. Поэтому это все еще одна команда, и отвечает всем требованиям для вопроса.
Кодзиро
@nux, я не согласен с поправками. 1) две столицы ошибочны, я намеревался чередовать команды во фразе. 2) многоточие - это вопрос стиля; пожалуйста,
впустите
1
хорошо, извини, я думал, что это будет выглядеть лучше.
Nux
в моей системе он не сохраняет папку 3 как ~ / folder1 / folder3, а скорее копирует все содержимое в folder3 в folder1
alpha_989
23

Вы можете создать сценарий справки или сделать это с xargsпомощью функции печати (в данном случае echo):

echo firstDir secondDir | xargs -n 1 cp test

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

Эвандро Сильва
источник
Это, пожалуй, лучший / самый прямой ответ на вопрос
Брайсон С.
7

После долгих поисков эта работа как Шарм тоже!

for dir in *; do [ -d "$dir" ] && cp /path/file.txt "$dir" ; done

Это скопирует файл file.txt в каждый каталог вашего текущего местоположения в терминале.

for dir in *; do [ -d "$dir" ] && cp -rf /path/folder "$dir" ; done

Это скопирует папку в каждый подкаталог вашего текущего местоположения в терминале.

Я разделяю это, надеюсь, что это помогает другим.

Nux
источник
В zsh, вы можете использовать for i in *(/); ...для циклического перебора всех подкаталогов, чтобы избежать [ -d ...теста. Расширенная глобализация - одна из причин, по которой мне это нравится bash.
Rmano
можете ли вы снова
ввести
1
В zshпервую команду этого ответа можно упростить как for dir in *(/); do cp /path/file.txt "$dir"; done. См. Zsh.sourceforge.net/Intro/intro_2.html
Rmano
5
Вы можете отменить тест в любой оболочке, производной от Bourne, сfor dir in */;
Henk Langeveld
@nux Это работает очень хорошо, и за командой очень легко следовать. За это надо голосовать намного выше!
nukeguy
1

Если вы хотите скопировать файл test.txt в каждый каталог в / tmp / target / ...

создать тестовую среду:

mkdir /tmp/target
cd /tmp/target
mkdir -v {folder1,folder2,folder3}
touch test.txt

скопируйте это:

find * -maxdepth 0 -type d -exec cp -vi test.txt {} \;
матовый
источник
0

Просто подумал дать вариант ответа Sylvain Pineau

где dir1и dir2нет в вашем текущем каталоге.

find ./ -maxdepth 2 -type d -name dir1 -exec cp file.txt {} \;

Здесь команда find будет искать dir1два уровня или вы можете пропустить -maxdepthпараметр для поиска dir1во всех папках в текущем каталоге и под ним.

Joshi
источник