Копіювання одного файлу в декілька каталогів за допомогою cp


12

Це питання є продовженням свого роду попередніх запитань: Створення численних каталогів з використаннямmkdir .

Я використовую bashоболонку. Я створив п'ятдесят каталогів, кожен починаючи з префікса "s", використовуючи команду:

mkdir $(printf "s%02i " $(seq 1 50))

які прокладки до другої цифри з нулями. Тобто каталоги , які я отримую мають вигляд s01, s02, ..., s49, s50.

Тепер я хотів би cpскопіювати один файл (наприклад, test.txt) у кожен із п'ятдесяти каталогів. Чи можливо це зробити аналогічно вищевказаному? Наприклад, чи працювала б така робота? Я відносно новий в Unix / Linux, тому не дуже хочу це намагатися, поки хтось, будь ласка, не вкаже мені, що це безпечно.

cp test.txt $ (printf "s% 02i.txt" $ (seq 1 50))

Переглядаючи manсторінку для cp, схоже, це не cpпідтримує декілька напрямків, як це:

NAME
       cp - copy files and directories

SYNOPSIS
       cp [OPTION]... [-T] SOURCE DEST
       cp [OPTION]... SOURCE... DIRECTORY
       cp [OPTION]... -t DIRECTORY SOURCE...

DESCRIPTION
       Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

       Mandatory  arguments  to  long  options are mandatory for short options
       too.

Відповіді:


7

Якщо ви хочете використовувати вихід з вашої команди, щоб скопіювати файл у кожен каталог за допомогою cp, ви завжди можете передавати його на xargs:

printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt

Не повинно виникнути жодних сумнівів щодо безпеки розбору виводу, оскільки ви знаєте його формат і вміст до цього часу - ризик зустріти мета символи та пробіл у назвах файлів тут насправді не проблема.

Крім того, якщо припустити, що каталоги вже існують, ви можете спробувати щось на кшталт:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}

або без труби:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;

Останні дві команди знайдуть будь-які файли в поточному каталозі та cp test.txtдо них. Ця -maxdepth 1опція дозволить уникнути будь-яких підкаталогів, які також отримують файл. Майте в виду , що 's[0-9][0-9]'у відповідність з sподальшим будь-якими двома цифрами, а це значить , якщо з якоїсь - то причини у вас є s99в cwd, він також отримує копію test.txt.


8

Ви також можете дозволити оболонці робити ітерації за допомогою forциклу. Це найосновніший спосіб, який не покладається на зовнішні інструменти на кшталт parallelабо xargs, і мені це найлегше зрозуміти:

for name in $(printf "s%02i " $(seq 1 50)); do
    mkdir $name
    cp test.txt $name
done

Є мільйон інших способів написати це, наприклад:

for name in $(seq -w 1 50); do
    mkdir s$name
    cp test.txt s$name
done

Якщо ви хочете перевірити, що було б виконано, перш ніж це зробити, ви можете зробити щось на кшталт попереднього попередження команд echo, які будуть друкувати рядок, а не виконувати його:

for name in $(seq -w 1 50); do
    echo mkdir s$name
    echo cp test.txt s$name
done

Виходи:

mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.


2

Ви також можете використовувати паралельно GNU . Якщо припустити, що ви перебуваєте в каталозі, що містить text.txt, а ваші 50 dirs розташовані в /my/50dirs/path(наприклад /my/50dirs/path/s01, /my/50dirs/path/s02тощо), ви б запустили:

seq -w 01 50 | parallel -j1 cp text.txt /my/50dirs/path/s{}

2
Краще зробіть це parallel -j1, інакше буде одна робота на ядро, а на багатоядерній машині завдання змагатимуться за IO.
Жил "ТАК - перестань бути злим"
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.