Копіюйте лише звичайні файли з одного каталогу в інший


12

Я хотів би скопіювати вміст каталогу 1 в каталог 2. Однак я хотів би скопіювати файли (а не каталоги) зі свого каталогу 1. Як це зробити?

cp dir1/* dir2/*

тоді я все ще маю каталоги.

Крім того, всі мої файли не мають жодного розширення . не зробить трюку


1
Не знаю, які розширення стосуються цього.
ctrl-alt-delor

1
cp dir1/* dir2абоcp -t dir2 dir1/*
ctrl-alt-delor

@richard Існує досить поширена звичка, що виходить із світу DOS, не використовувати розширення для каталогів, яка все ще певною мірою зберігається, і змушує деяких людей припускати, що якщо є крапка, то це не каталог і навпаки.
Жил "ТАК - перестань бути злим"

гаразд, але все-таки не сприймати
ctrl-alt-delor

Відповіді:


18
cp dir1/* dir2

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/*збігається з декількома файлами і останній збіг є, ви отримаєте повідомлення про помилку.
      • Якщо останній збіг dir/*- це каталог, всі інші збіги будуть переміщені до нього.
  • Якщо dir2це не порожньо, це знову залежить:
    • Якщо останній збіг dir2/*- це каталог, dir1/*а інші збіги dir2/*буде переміщено в.
    • Якщо останній збіг dir2/*є файлом, ви, ймовірно, отримаєте повідомлення про помилку, якщо не dir1/* відповідає лише одному файлу.

$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).вихід із статусом 1 для мене.
contrebis

1
Так, для мене також є вихід зі статусом 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виходить із ненульовим кодом виходу, оскільки він не міг зробити все, що йому сказали. Це не означає, що він нічого не робить .
Adaephon

3
Звичайно, я думав, що варто зауважити, тому що якщо ви поєднуєте команди разом із &&цим, це може спричинити проблеми. Я намагався щось подібне, хоча зараз не пам'ятаю контекст.
contrebis

Це не копіює приховані файли.
фельдшер

@felwithe Чи *включає приховані файли чи як включити приховані файли, залежить від оболонки. Якщо пристрій *не включає приховані файли, ви можете зіставити їх .*. Зверніть увагу , що це буде включати в себе .і ..на bashі , dashале не на zsh. У контексті цієї відповіді ви можете піти з , cp dir1/* dir1/.* dir2тому що .і ..каталоги і не будуть скопійовані. zshможна також включати приховані файли із *(D).
Adaephon

7

Це оболонка, яка розширює символи, а не команди. Тож cp dir1/* dir2/*спочатку розширюються дві маски, а потім викликає cpрезультат. Це зовсім не те, що ви, очевидно, очікуєте: залежно від того, скільки файлів уже є dir2, dir2/*може розширюватися до одного або декількох аргументів. Команда cpне знає, який з її аргументів виник через розширення першого шаблону, а які - з розширення другого шаблону. Очікує, що його останнім аргументом буде ім'я каталогу призначення. Таким чином, щоб скопіювати всі файли з каталогу dir1в каталог dir2, останнім аргументом повинен бути каталог dir2:

cp dir1/* dir2

Оскільки *відповідає всім файлам, cpнамагається скопіювати всі файли. Сюди входять каталоги: каталоги також є файлами. Він пропускає каталоги, але повідомляє про помилку. Він копіює вміст спеціальних файлів, таких як іменовані канали (щось краще було б записати до них або cpзаблокувати) тощо.

Щоб копіювати лише звичайні файли, потрібно обмежити відповідність. У zsh ви можете використовувати класифікатор глоба . для цього:

cp dir1/*(.) dir2

Інші снаряди цього не мають. За допомогою findкоманди можна фільтрувати типи файлів. Якщо припустити, що ви використовуєте невбудований Linux або Cygwin:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

На Linux, FreeBSD та OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2

Чи є причина вказувати -maxdepth 1. Також, чи є спосіб рекурсивно копіювати та зберігати оригінальну ієрархію каталогів у каталозі призначення?
Абдулл

@Abdull Без -maxdepth 1цього findкоманда повторно повториться у підкаталоги, чого тут не було бажано. Якщо ви хочете скопіювати всі дерево каталогів , включаючи підкаталоги, це зовсім інше питання, і відповідь на нього набагато простіше: cp -a dir1 dir2.
Жиль "ТАК - перестань бути злим"

0

Нижче наведено команду для копіювання файлу з джерела в каталог призначення.

  1. Перейдіть до вихідної папки, а потім напишіть команду нижче:

    $ cp fileName destination directory path

Приклад:

cp publichOT.sh  /data/home/useradmin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.