BASH скопировать все файлы, кроме одного

Я хотел бы скопировать все файлы из каталога, кроме одного с именем Default.png. Кажется, что есть несколько способов сделать это. Что вам кажется наиболее эффективным?


person Joe Cannatti    schedule 21.08.2009    source источник
comment
Зачем вам это нужно, чтобы пропустить этот файл, а не просто удалить его после копирования? Он уже существует в целевом каталоге?   -  person Lasse V. Karlsen    schedule 21.08.2009
comment
Да, файл с таким именем уже находится в целевом каталоге.   -  person Joe Cannatti    schedule 22.08.2009
comment
@LasseV.Karlsen: Или вы можете сэкономить время на его копировании, если это большой файл. Меня это интересует, но исключая каталог, а не файл.   -  person Nikana Reklawyks    schedule 20.11.2012


Ответы (6)


Просто, если src/ содержит только файлы:

find src/ ! -name Default.png -exec cp -t dest/ {} +

Если src/ имеет подкаталоги, они будут пропущены, но файлы внутри них будут скопированы:

find src/ -type f ! -name Default.png -exec cp -t dest/ {} +

Если src/ имеет подкаталоги, это не рекурсивно в них:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +
person John Kugelman    schedule 21.08.2009
comment
Это оказывается лучшим для меня, потому что кажется, что OS X поставляется без включенного glob. - person Joe Cannatti; 22.08.2009
comment
@Max \; выполняет команду один раз для каждого файла. + запускает команду один раз и передает ей сразу все имена файлов (с учетом ограничения длины командной строки). + в целом немного эффективнее. - person John Kugelman; 22.09.2014

Должно быть следующим:

cp -r !(Default.png) /dest

При копировании в папку, вложенную в текущую папку (называемую примером в приведенном ниже случае), вам также необходимо опустить этот каталог:

cp -r !(Default.png|example) /example
person Jon    schedule 21.08.2009
comment
Это создает -bash: !: событие не найдено - person Joe Cannatti; 21.08.2009
comment
Вы копируете файлы в папку, вложенную в папку, из которой вы копируете? - person Jon; 21.08.2009
comment
Для этого требуется shopt -s extglob, если он отключен. - person Barry Kelly; 21.08.2009
comment
Кажется, что OS X нужно использовать shopt -s extglob, как описано @BarryKelly. При этом работает идеально. - person Kat; 09.07.2014
comment
Годы на Баше и не знали о !()... Красиво! Для тех, кто -- как и я -- считает, что пришло время изучить/пересмотреть bash, вот соответствующие ссылки, относящиеся к этому вопросу/ответу: shop/extglob и шаблон. - person Brandt; 26.11.2019
comment
Просто потому, что я сначала не совсем понял, как это использовать: cp -r $src_path/!($file) $dest_path было бы эквивалентно cp $src_path/* $dest_path/ --exclude $file, если бы у cp был такой аргумент. - person mazunki; 12.07.2020

rsync долгое время был моей заменой cp/scp:

rsync -av from/ to/ --exclude=Default.png

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
person matja    schedule 21.08.2009
comment
Если я хочу исключить два разных файла, как мне это использовать? - person Pulkit Bansal; 14.11.2018
comment
поддерживаются несколько аргументов --exclude=. И не забудьте аргумент -r, если вы синхронизируете каталоги. - person Rian Sanderson; 27.04.2019
comment
Обратите внимание, что он также копирует скрытые файлы (например, .git) и в случае одних и тех же файлов перезаписывает их. - person Islam Murtazaev; 13.11.2020
comment
thisrsync -aP --exclude=backup /root/jenkins_api/* /root/jenkins_api/backup не работает, если в /root/jenkins_api/** нет файлов. Есть ли способ пропустить, если файлы не найдены? - person Youssef Boudaya; 24.06.2021

Я бы просто сделал:

cp srcdir/* destdir/ ; rm destdir/Default.png

если файлы не большие. В противном случае используйте, например.

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
person nos    schedule 21.08.2009
comment
Первая команда - это не то, о чем просил ОП. Если Default.png существует в двух каталогах, он заменит тот, что в destdir, на тот, что в srcdir, а затем удалит скопированный Default.png. Вместо этого ОП хочет сохранить Default.png, который уже существует в destdir. - person SnowFrog; 22.05.2017
comment
как насчет того, что файл default.png уже существует в каталоге назначения? Ваше решение не сработает. - person Iman Mohamadi; 03.06.2018

используйте параметр расширения оболочки с регулярным выражением

cp /<path>/[^not_to_copy_file]* .

Все будет скопировано, кроме файла not_to_copy_file

-- если с этим что-то не так. пожалуйста уточни !

person alex    schedule 02.04.2020
comment
Добро пожаловать в СО. К сожалению, ваш ответ неверен. Выражение в квадратных скобках ([...]) содержит набор символов для сопоставления, а ^ в начале приведет к совпадению дополнения перечисленных символов. В следующем примере ни один из файлов не будет указан в списке: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*, поскольку будут исключены все имена файлов, начинающиеся с любого из следующих символов: _cefilnopty. - person rtx13; 02.04.2020

person    schedule
comment
Это с большей вероятностью приведет к ошибкам, чем сделает то, что вы намеревались. - person Dennis Williamson; 22.08.2009
comment
хорошо, @DennisWilliamson, можешь объяснить, почему? - person arthur.sw; 02.03.2021
comment
@arthur.sw Во-первых, он не учитывает файлы с пробелами. Как и во многих случаях, связанных с оболочкой, есть множество крайних случаев, которые не работают. В 95%+ случаев этот материал просто работает. Просто нужно знать о предостережениях. Пробелы в именах файлов превращают работу с оболочкой из тривиальной в болезненную. - person Will Hartung; 02.03.2021