Comments 67
Мало того, rsync — не единственный способ. Однако, во-первых, он не в входит в стандартную поставку множества дистрибутивов. А во вторых — цель топика не показать одну строчку «как сделать», а рассказать, о том как самому искать решения не изобретая велосипедов.
Или вы думаете что топику не место на хабре?
Или вы думаете что топику не место на хабре?
+11
этому топику — место. исходному — место в QA
+2
этому топику — местону скажем так, вроде информация годная, но вот статьёй это назвать тяжело. Это можно свернуть в комментарий к предыдущей «статье», до фразы: «смотри на find и прочитай в man'е, что у cp есть ключ --parents».
-1
а у find есть ключи name и exec. а так же возможность комбинировать ключи через опции -o, -a и скобки. Но кому это интересно?) Читать маны — не модно.
+1
«читаю man'ы — $10, читаю man'ы с выражением — $15» ©
+3
exec, если я не ошибаюсь, есть только в GNU find
-name и ещё -regex, если уж говорить об исходной задаче — укоротили-бы решение, но главной целью было показать возможности конвейера.
-name и ещё -regex, если уж говорить об исходной задаче — укоротили-бы решение, но главной целью было показать возможности конвейера.
0
Конвейер не предназначен для передачи имён файлов. В ссылке ниже подробное объяснение этому чуду.
exec есть и в POSIX версии. Даже + на конце exec'a там есть, если я не ошибаюсь.
exec есть и в POSIX версии. Даже + на конце exec'a там есть, если я не ошибаюсь.
+1
Да, вы правы про exec, видимо у меня сложилось неверное впечатление после того как лет 10 назад я не нашел его в man-e
0
UFO just landed and posted this here
Ссылка не съелась. Я просто ссылался на свой комментарий ниже.
+1
$ man cp | grep parents | wc -l
0
0
0
Я бы сказал, что это не статья, а часть серии статей о том как писать скрипты. И видя заголовок «как решить то-то», я жду решение, а не экскурс в анализ и знание различных утилит окружения GNU.
0
Вы знаете, когда я только начинал изучать unix-like системы, главное чему я был поражен — это следование принципу «от понимания к действию» и прочитав одну статью становилось возможным решать весь класс подобных проблем. И этим статьи отличались от «howto» которые как вы и предлагаете — описывали последовательность действий необходимую для достижения конкретного результата в конкретных условиях.
Однако, мне кажется, что хабр уж точно не место для однострочных howto. А эта информация, возможно, поможет кому нибудь понять как решаются такие задачи.
Однако, мне кажется, что хабр уж точно не место для однострочных howto. А эта информация, возможно, поможет кому нибудь понять как решаются такие задачи.
+13
UFO just landed and posted this here
Отличная статья, познавательная. Спасибо!
На самом деле многому учит.
На самом деле многому учит.
0
Для подстановки аргументов ещё можно использовать конструкцию $() внутрь которой мы помещаем файнд с грепом, а всё это целиком отдаём cp в качестве аргумента.
0
Читать до полного просветления.
Автору исходного поста, кстати, тоже не помешало бы.
А ещё не помешало бы почитать man find и использовать вместо find | grep -v кошерную конструкцию
И вообще, если вы такой противник rsync'a, то задача решается одним find'ом на раз два:
А в целом, в статье я увидел лишь полное нежелание читать маны, стремление использовать странные решения и преподносить это как способ «как самому искать решения не изобретая велосипедов».
Автору исходного поста, кстати, тоже не помешало бы.
А ещё не помешало бы почитать man find и использовать вместо find | grep -v кошерную конструкцию
find /path ! -name "*exclude*"
И вообще, если вы такой противник rsync'a, то задача решается одним find'ом на раз два:
find /path -type f ! -name "*exclude*" -exec cp --parents -t /target/dir "{}" \+
А в целом, в статье я увидел лишь полное нежелание читать маны, стремление использовать странные решения и преподносить это как способ «как самому искать решения не изобретая велосипедов».
+6
Вы правы, в случае, если в качестве исходного списка файлов у нас выступает файловая система — можно использовать find и множество других утилит. Топиком я хотел показать как решать подобный класс задач — комбинированием утилит. Ведь как только мы начинаем брать список файлов, например из файла, find нам уже не поможет.
Вообщем, судя по обилию комментариев с непониманием исходной цели топика, что-то было написано не так и его лучше убрать.
Вообщем, судя по обилию комментариев с непониманием исходной цели топика, что-то было написано не так и его лучше убрать.
+2
В таком случае, стоило сделать акцент на этом в самом топике. В противном случае тонны конструктивной критики выльются на вас. И комментирующие будут правы.
А в случае чтения списка из файла, стоит тогда включить проверку, есть ли вообще такой файл, и не сломает ли что запускаемая команда.
Вы просто выбрали неудачный пример для того, что хотите продемонстрировать.
А в случае чтения списка из файла, стоит тогда включить проверку, есть ли вообще такой файл, и не сломает ли что запускаемая команда.
Вы просто выбрали неудачный пример для того, что хотите продемонстрировать.
-1
Если вы хотите что-то продемонстрировать, как то «брать список файлов, например из файла» — так и делайте именно так. Не надо подавать дурных примеров. Те, кто будет это читать, скорее всего не знают о том, что умеет find сам по себе, а стоило бы.
-1
Внес изменения в исходный топик, добавлен дискламер, и готовый рецепт для этой конкретной задачи.
Однако не могли-бы Вы пояснить почему вы считаете использование более универсальных методов дурным примером?
Однако не могли-бы Вы пояснить почему вы считаете использование более универсальных методов дурным примером?
+1
Вы же хотите научить хорошему? Тогда надо учить использовать для каждой задачи подходящий инструмент. Я вполне допускаю, что когда времени нет, лень посмотреть ман, и набрал в консоли первое, что в голову пришло — это одно, но не надо это показывать в качестве обучающего материала. Автор, который осмелился учить чему-то остальных, должен нести большую ответственность.
off
Может быть я брюзжу тут как старый дед =), но уж больно универсалов много развелось, орудующих одним молотком по всем гвоздям, специалистов вот только не найти. И куча how-to в сети только способствует.
+2
Насколько я понял, проблема в том, что очень общую тему я объяснил на примере излишне конкретной задачи.
Думаю, стоит написать отдельный топик, с большим количеством теории и рассмотрев больше примеров, про который нельзя будет сказать что «это решается одной командой». Но так уж получилось, что я собрался написать статью именно в ответ на тот топик.
Думаю, стоит написать отдельный топик, с большим количеством теории и рассмотрев больше примеров, про который нельзя будет сказать что «это решается одной командой». Но так уж получилось, что я собрался написать статью именно в ответ на тот топик.
off reply
Мне кажется, что непрофессионализм, частным случаем которого является поверхностный подход (естественно, подразумевая ситуации, где такой подход не допустим) — является скорее свойством личности, а не результатом неправильного обучения
0
Никогда не понимал, что означает конструкция
"{}" \+
в конце find-а?+1
Очень полезная штука. find с \; запускает по одному процессу на каждый найденный файл. find с \+ на конце группирует файлы и запускает по одному процессу на много файлов. Экономия времени и ресурсов, однако. Появилась лет 7 назад.
С вас 10$ за краткую выжимку из man'а =)
С вас 10$ за краткую выжимку из man'а =)
+6
man find говорит нам, что:
Строка `{}' будет заменена именем текущего обрабатываемого файла
+1
У меня этот вариант работает и без слеша. Но безопаснее/привычнее экранировать.
Вообще есть 2 варианта запуска find -exec:
Попытка скопировать это и выполнить в шелле провалится, т.к. шелл съест «; ». Чтоб символ дошёл до find, его экранируют от шелла слешем.
Ещё можно взять в кавычки с тем же эффектом:
Вообще есть 2 варианта запуска find -exec:
find -exec echo {} ;
find -exec echo {} +
Попытка скопировать это и выполнить в шелле провалится, т.к. шелл съест «; ». Чтоб символ дошёл до find, его экранируют от шелла слешем.
Ещё можно взять в кавычки с тем же эффектом:
find -exec echo {} ';'
+1
Вместо 'xargs cp --parents' можно использовать 'cpio -pd'
0
Необязательно писать
find ./
, достаточно find .
. Меньше набирать, и выглядит красивее.0
Годная статья. Спасибо.
Как раз недавно задавался подобным вопросом.
Вообще надо будет ознакомиться и начать использовать такие true-юниксойдные штуки, как sed, awk, xargs, find, for, узнать больше о любимом grep. :) Отпугивает то, что выглядит всё это по-шамански сложно.
Как раз недавно задавался подобным вопросом.
Вообще надо будет ознакомиться и начать использовать такие true-юниксойдные штуки, как sed, awk, xargs, find, for, узнать больше о любимом grep. :) Отпугивает то, что выглядит всё это по-шамански сложно.
0
Пожалуйста.
Не бойтесь, главное преимущество этого подхода то, что каждая отдельная утилита достаточно проста.
Ваш любимый grep выполняет одну функцию — фильтрует. Просто делает он это кучей разных способов, но вам-же не обязательно изучать их все сразу — просто имейте ввиду что grep может отфильтровать всё что угодно, а конкретные параметры всегда можно посмотреть в man в тот момент, когда они понадобятся.
Не бойтесь, главное преимущество этого подхода то, что каждая отдельная утилита достаточно проста.
Ваш любимый grep выполняет одну функцию — фильтрует. Просто делает он это кучей разных способов, но вам-же не обязательно изучать их все сразу — просто имейте ввиду что grep может отфильтровать всё что угодно, а конкретные параметры всегда можно посмотреть в man в тот момент, когда они понадобятся.
+2
А у меня есть файлы с переводами строк в именах (да, перевод строки — допустимый символ). Как там grep отработает? Подсказываю: неправильно :)
+2
Значит вам, очевидно, нужно будет использовать способы отличные от описанного в основной части топка. Например — один из готовых рецептов в заключении.
0
Я к этому и веду, что стоит написать, что всё это хорошо, но неверно. А сейчас написано «Задача решена», как будто это верное решение. А в заключении эквивалентное решение.
0
Вы правы, исправил формулировку.
0
На самом деле тема многострочной фильтрации не сказать, что хорошо раскрыта. На последнюю задачу выковыривания данных из постраничного вывода я убил приличное количество времени, а от переводов избавлялся с помощью tr`а, что ну никак нельзя назвать элегантным решением. Был бы рад увидеть обзорную статью на эту тему, например. Начинание то у вас хорошее.
0
Если найду время написать, то обязательно затрону тему сепараторов и экранирования
0
Декомпозиция требует первым делом выписать все файлы, а спасает от первичного формирования громадной простыни юниксовая потоковость команд, да? Без возможности организовать поток такой подход был бы чреват неэффективным использованием ресурсов, для предварительного формирования того огромного списка…
0
некогда озаботился проблемой сложного копирования файлов, пробовал xcopy, robocopy итп и пришел к выводу что во многих ситуациях нужно писать скрипт. Тогда сел и в качестве развлечения написал свою консольную программку для копирования. Основной фишкой которой было разделение ключей для копирования на ключи для файлов и пля папок. Так же реализовал возможность задания множества масок для каждого ключа. С тех пор перестал пользоваться вышеуказанными утилитами и по мере нужды добавляю в свою прогу новые возможности. На данный момент уже получился хороший список, и точно могу сказать, то что в этой проге можно сделать одним запуском проги в других, без написания скрипта не получится. Кому интересно тут последняя альфа. Если кому что то надо добавить обращайтесь.
0
маленький пример:
скопирует файлы с масками *.txt *.doc *.pdf исключив файлы с масками __*.pdf bak*.doc ~*.pdf из папок с масками Doc* Scan пропуская в них папки с масками Temp Tmp
где:
если надо перезаписать то добавить /OF
если в каких то папках ненадо проверять маски файлов то /XDMF или /XDMD
и.т.п
в этой программке Вас многое, надеюсь приятно, удивит
copymik "c:\Папка откуда" "d:\Папка куда" /MF *.txt *.doc *.pdf /MD Doc* Scan /XCF __*.pdf bak*.doc ~*.pdf /XCD Temp Tmp
скопирует файлы с масками *.txt *.doc *.pdf исключив файлы с масками __*.pdf bak*.doc ~*.pdf из папок с масками Doc* Scan пропуская в них папки с масками Temp Tmp
где:
Заголовок спойлера
[/MF[ МаскаФайла1[ МаскаФайла2[ ....]]]] Маска для копирования файлов (по умолчанию маска * — все)
[/MD[ МаскаПапки1[ МаскаПапки2[ ....]]]] Маска для копирования папок (по умолчанию маска * — все)
[/XCD [МаскаПапки1[ МаскаПапки2[ ....]]]] Не копировать папки с указанными масками (по умолчанию маска * — все)
[/XCF [МаскаФайла1[ МаскаФайла2[ ....]]]] Не копировать файлы с указанными масками (по умолчанию маска * — все)
[/MD[ МаскаПапки1[ МаскаПапки2[ ....]]]] Маска для копирования папок (по умолчанию маска * — все)
[/XCD [МаскаПапки1[ МаскаПапки2[ ....]]]] Не копировать папки с указанными масками (по умолчанию маска * — все)
[/XCF [МаскаФайла1[ МаскаФайла2[ ....]]]] Не копировать файлы с указанными масками (по умолчанию маска * — все)
если надо перезаписать то добавить /OF
если в каких то папках ненадо проверять маски файлов то /XDMF или /XDMD
Заголовок спойлера
[/XDMD МаскаПапки1[ МаскаПапки2[ ....]]] Не проверять маску папки для подпапок с указанной маской (будет использована маска * — все)
[/XDMF МаскаПапки1[ МаскаПапки2[ ....]]] Не проверять файловую маску для подпапок с указанной маской (будет использована маска * — все)
[/XDMF МаскаПапки1[ МаскаПапки2[ ....]]] Не проверять файловую маску для подпапок с указанной маской (будет использована маска * — все)
и.т.п
в этой программке Вас многое, надеюсь приятно, удивит
0
Ребята подскажите как мне исправить.
У меня в результате находит файл но при копировании подставляет «To: office@vp.com». А как сделать так что бы подставляло только пусть?
find /home/vmail/vp/cur/ -type f -exec grep -H "To: office@vp.com" {} \; | xargs -n 1 -I % cp --parents "%" /home/OFFICE/
У меня в результате находит файл но при копировании подставляет «To: office@vp.com». А как сделать так что бы подставляло только пусть?
0
Sign up to leave a comment.
Как правильно скопировать файлы и папки исключая некоторые из них