Дублювати файл x разів у оболонці команди


22

Я намагаюся дублювати відео файл x разів з командного рядка, використовуючи цикл for, я спробував це так, але це не працює:

for i in {1..100}; do cp test.ogg echo "test$1.ogg"; done

5
Чи не є вашою єдиною помилкою те, echoчого там не повинно бути, а $1яке має бути $i?
Джулі Пелтьє,

якщо я видаляю ехо і використовую лише test$1.oggтоді, він говорить: test.ogg і test.ogg - це одні і ті ж файли , тому здається, що $ 1 не розпізнається?
Чорний

@EdwardBlack: Звучить так, що я неправильно зрозумів ваші вимоги. Це рішення не підходить.
cuonglm

@JuliePelletier, чорт, мені трапляється іноді, що я випадково пишу $1замість $i, це рано вранці, вибачте ... дякую. Я буду використовувати $xв майбутньому замість$i
Чорний

Відповіді:


25

Ваш код оболонки має два випуски:

  1. Там echoне повинно бути.
  2. Змінна $iвведена неправильно, як $1у назві файла призначення.

Щоб зробити копію файлу в тому ж каталозі, що і сам файл, використовуйте

cp thefile thecopy

Якщо ви вставите щось інше туди, напр

cp thefile theotherthing thecopy

то передбачається, що ви хочете скопіювати thefileі theotherthingв каталог, який називається thecopy.

У вашому випадку він спеціально шукає файл з назвою test.oggта ім'ям echoдля копіювання в каталог test$1.ogg.

$1, Швидше за все , розшириться до порожньому рядку. Ось чому при видаленні команди echoз команди ви отримуєте "test.ogg і test.ogg - ті самі файли"; команда, що виконується, по суті

cp test.ogg test.ogg

Це, мабуть, непорозуміння.

Зрештою, ви хочете щось подібне:

for i in {1..100}; do cp test.ogg "test$i.ogg"; done

Або, як альтернатива

i=0
while (( i++ < 100 )); do
  cp test.ogg "test$i.ogg"
done

Або, використовуючи tee:

tee test{1..100}.ogg <test.ogg >/dev/null

Примітка. Це, швидше за все, може працювати в 100 примірниках, але для тисяч примірників це може призвести до помилки "аргумент задовго". У цьому випадку поверніться до використання циклу.


12

Короткий і точний

< test.ogg tee test{1..100}.ogg

а ще краще робити

tee test{1..100}.ogg < test.ogg >/dev/null

див. використання команд трійника для отримання додаткової допомоги.

Оновлення

як запропонував @Gilles, використання teeдефекту не зберігає метаданих файлів. Щоб подолати цю проблему, можливо, після цього потрібно запустити команду нижче:

cp --attributes-only --preserve Source Target

3
Це потенційно швидше, ніж багаторазові дзвінки cp(залежить від розміру файлу відносно наявної пам'яті), але має дефект не збереження жодних метаданих файлів.
Жил "ТАК - перестань бути злим"

@Gilles ох, ми можемо це подолати?
Рахул

3
Ви можете бігти cp --attributes-onlyпісля цього.
Жил "ТАК - перестань бути злим"

@Gilles спасибі, оновив мою відповідь відповідно до вашої допомоги.
Рахул

FWIW жоден з інших відповідей також не використовується cp -pдля збереження метаданих.
roaima

11
for i in {1..100}; do cp test.ogg "test_$i.ogg" ; done

1
Слід зазначити змінні розширення.
кіт

1

Наступна команда копіює файл.a 5 разів:

$ seq 5 | xargs -I AA cp file.a fileAA.a

Якщо ви віддаєте перевагу dd (не те саме, що cp!):

$ seq 5 | xargs -I AA dd if=file.a of=fileAA.a

0

Ви не викликали змінну i під час копіювання

використовувати нижче сценарій. Як перевірено, він працював чудово

for i in {1..10}; do cp -rvfp test.ogg test$i.ogg ;done

3
Це те саме, що два попередні відповіді та коментар, за винятком (1) питання задає близько 100, а у Вашій відповіді використовується 10, (2) Ви необов’язково додали -rvfваріанти cp, і (3) Ви не змогли цитувати змінне розширення . (Також зауважте, що звичайно мати пробіл між знаками пунктуації на зразок ;та наступним словом.) Додавання цього -pпараметра є цінним, але (4a) воно вже вирішено (у коментарях), і (4b) ваша відповідь не є корисно, якщо ви не поясните, що ви робите.
Скотт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.