Як скопіювати деякі, але не всі файли?


54

Таким чином, ви можете використовувати *знак підключення для всіх файлів при використанні cpв контексті каталогу. Чи є спосіб скопіювати всі файли, крім xфайлу?

Відповіді:


42

У bashви можете використовувати extglob:

 $ shopt -s extglob  # to enable extglob
 $ cp !(b*) new_dir/

де !(b*)виключити всі b*файли.

Пізніше ви можете відключити за extglobдопомогою

 $ shopt -u extglob

Чи знаєте ви, чи є щось еквівалентне для оболонки tcsh?
Левон

На жаль, я цього не роблю. Здається, findце єдиний спосіб tcsh:find . -maxdepth 1 ! -name "exclude*" -exec cp -t destination {} \+
поспішити

50

Rsync прекрасно справляється з цим.

Приклад копіювання всіх: rsync -aP /folder1/* /folder/2

Приклад копіювання всіх із виключенням: rsync -aP --exclude=x /folder1/* /folder2/

-aPперемикач:

a: Подібно до cp -a, рекурсивного тощо. P: Показує прогрес, приємна особливість rsync.


5
І перегляньте цю відповідь для короткого посібника до загальних списків виключень rsync.
Жил "ТАК - перестань бути злим"

1
У darwin / MacOS використовуйте -rPзамість, -aPякщо ви хочете повторити. -aпризначено для архівування. Не впевнений, чи це змінилося, чи це просто інше на MacOS.
jpoveda

rsyncмає можливість зробити це рекурсивним. Приклад: rsync --recursive -P --exclude=x /folder1/* /folder2/. (Тестовано лише на Ubuntu)
n1k31t4

12

Це не особливість cp, це особливість вашої оболонки (вона розширює, *щоб означати всі неточні файли), тому відповідь залежить від того, яку оболонку ви використовуєте. Наприклад, zshпідтримує цей синтаксис:

$ cp ^x /path/to/destination

Де ^xозначає "всі файли, крім x"

Ви також можете комбінувати схеми вибору та де-виділення, наприклад, для копіювання всіх файлів WAV, крім тих, що містять xyz, ви можете використовувати:

cp *.wav~*xyz*

Будь-які коментарі bash?
Чад Гаррісон

@hydroparadise Я не знаю багато про баш, але ця відповідь, схоже, охоплює це
Майкл Мрозек

Що з tcsh? Хтось знає?
Левон

4

Можна також виконати звичайну стару (портативну / сумісну) обробку Bourne різними способами зі стандартними інструментами набагато менш елегантними способами, ніж використання вдосконалених обшивок оболонок або команд із вбудованими параметрами виключення.

Якщо файлів не надто багато (і не з іменами, включаючи пробіли та / або рядкові перерви), це може бути таким чином:

cp `ls | egrep -v '^excludename$'` destdir/.

Звичайно, bashінструменти GNU - чудові та потужні, але вони все ще не завжди доступні. Якщо ви маєте намір помістити його в портативний сценарій, я б рекомендував, findяк у коментарі Rush.


2
Я вважаю, що остання частина вашої відповіді просто відволікає увагу від теми. Крім того, "Unix" вже не є золотим стандартом (якщо він колись був). Це просто не так актуально, якщо щось є "Unix" чи ні більше, незважаючи на те, що назва цього веб-сайту "Unix та Linux".
Олександр

2
ГАРАЗД. Я замість цього перемістив коментар: Unix - це не GNU. Я погоджуюся, що «неповторність» речей не дуже цікава, але я все одно вірю в переносимість і трохи знаю про вашу історію.
MattBianco

Повністю згоден з вами там.
Олександр

2

Якщо ви хочете скопіювати все в папку (включаючи підпапки) у певний підкаталог:

cp -R $(ls | grep -v '^subdir$') subdir/

Працює з sh, bash, zsh (принаймні).


1
Переконайте, що це не той самий намір, якcp -R * subdir/
roaima

1
Якщо ви використовуєте цю команду "cp -R * subdir /", bash / zsh намагався скопіювати "subdir" повторно. У вас з'являється помилка: "ім'я задовге (не скопійовано)".
user2707671

Влучне зауваження. Ваша пропозиція намагається уникати попередження від cp(не від bash/ sh), " cp: cannot copy a directory, ‘subdir’, into itself, ‘subdir/subdir’". Однак копія виконується правильно. На жаль, ваш варіант поєднується з будь-яким ім'ям файлу, що містить пробіл чи розділові знаки для оболонки. Дивіться unix.stackexchange.com/q/128985/135943
roaima

-1

extglob Я вважаю, що це найкращий спосіб.

Інший спосіб - використання cp $(ls --ignore=x) subdir/


Це порушиться з урахуванням будь-яких форм спеціальних символів у назви файлів. (Пробіли, нові рядки та $ін.) Ніколи не аналізуйте вихідні дані ls. unix.stackexchange.com/q/128985/135943
Wildcard
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.