Команда find дает такой вывод:
[root @ localhost /] # find var / log / -iname anaconda. * вар / Журнал / anaconda.log вар / Журнал / anaconda.xlog вар / Журнал / anaconda.yum.log вар / Журнал / anaconda.syslog вар / Журнал / anaconda.program.log вар / Журнал / anaconda.storage.log
После объединения с tar он показывает следующий вывод:
[root @ localhost /] # find var / log / -имя anaconda. * -exec tar -cvf file.tar {} \; вар / Журнал / anaconda.log вар / Журнал / anaconda.xlog вар / Журнал / anaconda.yum.log вар / Журнал / anaconda.syslog вар / Журнал / anaconda.program.log вар / Журнал / anaconda.storage.log
Но при отображении файла tar он показывает только один файл
[root @ localhost /] # tar -tvf file.tar -rw ------- root / root 208454 2012-02-27 12:01 var / log / anaconda.storage.log
Что я здесь не так делаю?
С xargs я получаю этот вывод:
[root @ localhost /] # find var / log / -iname anaconda. * | xargs tar -cvf file1.tar
Второй вопрос
Во время ввода / перед var, означает, find /var/log
почему он дает этот mesaage tar: удаление начального `/ 'из имен членов
[root @ localhost /] # find / var / log / -имя anaconda. * -exec tar -cvf file.tar {} \; tar: удаление начального `/ 'из имен членов /var/log/anaconda.log tar: удаление начального `/ 'из имен членов /var/log/anaconda.xlog tar: удаление начального `/ 'из имен членов /var/log/anaconda.yum.log tar: удаление начального `/ 'из имен членов /var/log/anaconda.syslog tar: удаление начального `/ 'из имен членов /var/log/anaconda.program.log tar: удаление начального `/ 'из имен членов /var/log/anaconda.storage.log
В простой форме, в чем разница между следующими двумя?
find var/log
а также find /var/log
find
командой вам следует указать поисковый запрос. Работает без порой, но не всегда.{} +
вместо{} \;
него сгруппировать результаты поиска в один аргументОтветы:
Примечание: см . Ответ @ Iain для более эффективного решения.
Обратите внимание, что
find
это вызовет-exec
действие для каждого найденного файла .Если вы запускаете
tar -cvf file.tar {}
для каждого выходного файлаfind
, это означает, что вы будете перезаписыватьfile.tar
каждый раз, что объясняет, почему у вас остался один архив, который содержит толькоanaconda.storage.log
- это последниеfind
выходные файлы .Теперь вы на самом деле хотите добавлять файлы в архив, а не создавать их каждый раз (это то, что
-c
делает опция). Итак, используйте следующее:-r
Опция добавляет к архиву вместо воссоздавать его каждый раз.Примечание. Заменить
-iname anaconda.*
на-iname "anaconda.*"
. Звездочка является подстановочным знаком и может быть расширена вашей оболочкой,find
даже не увидев ее. Чтобы предотвратить это расширение, заключите аргумент в двойные кавычки.Что касается
tar
удаления ведущих/
: архив должен содержать только относительные имена файлов. Если вы добавили файлы с лидирующими символами/
, они будут сохранены как абсолютные имена файлов, например, буквально означающие/var/…
на вашем компьютере.IIRC это просто предосторожность для
tar
реализаций, отличных от GNU, и таким образом безопаснее, потому что вы не будете перезаписывать ваши фактические данные/var/…
при извлечении архива, если он содержит относительные имена файлов.источник
tar
образом создать реальный архив на магнитной ленте, добавляя один файл за раз, перематывая ленту, а затем перечитывая все это каждый раз, чтобы добраться до конца, все это будет смехотворно медленным. Ваше решение подходит, только если вы записываете файл tar на диск.find /var/log/ -iname anaconda*
ничего не дают иfind /var/log/ -iname anaconda.*
дают выход, почему?find
. Так что, если у вас естьanaconda*
, и в вашей текущей папке есть что-то, например, с именемanaconda5
(соответствует этому шаблону), шаблон будет расширен иfind
будет отображаться-iname anaconda5
вместо-iname anaconda*
. Почему первый не работает, а второй работает, зависит от того, какие файлы находятся в вашем текущем каталоге. @max{} +
вместо этого,{} \;
чтобы сгруппировать результаты поиска в один аргументВы можете использовать что-то вроде:
Они
-print0
и-T
работают вместе, чтобы разрешить имена файлов с пробелами, символами новой строки и т. Д. В последнем-
сообщается, что tar читает входные имена файлов из stdin.Обратите внимание, что
-print0
должно прийти в конце вашего утверждения, согласно этому ответу . В противном случае вы, вероятно, получите больше файлов, чем ожидаете.источник
-name
опцию, вызывая ваше решение дляtar
всего каталога. Если это то, что вы хотите, вы можете сделать это проще,tar -cvf file.tar var/log
не используяfind
вообще.tar
- хорошая идея. Это определенно лучшее решение, если вы ожидаете, что пути могут содержать пробелы. Я бы даже назвал его лучшим с технической точки зрения, поскольку он надежен и эффективен. Но это требует дополнительных специальных знаний и того,find
и другогоtar
. Я предпочитаю подстановку команд в значительной степени только потому, что это более общий инструмент: узнайте, как использовать его один раз, а затем используйте его везде. (Но я признаю, что у меня Windows с оболочкой, где она всегда работает.) Извиняюсь, если мне показалось грубым.xargs
.-print0
опцию find , вам также нужна--null
опция tar .--no-unquote
оказывается, что это необходимо: имена файлов, содержащие обратную косую черту, в противном случае были бы неправильно обработаны. (Нет, это не гипотетически - я действительно создаю архив tar из чужого кода, содержащий имя файла сПопробуй это:
Вы пытались использовать
find
для-exec tar
. Но как-exec
работает опция, она запускает эту команду один раз для каждого найденного файла, что приводитtar
к перезаписи файла tar, который она создает каждый раз. Вот почему вы только закончили с последним. Кроме того, вам нужно поместить кавычки вокруг указанного вами шаблона,find
чтобы оболочка не раскрыла его перед передачейfind
.Используя подстановку команд с помощью обратных кавычек (или используя
$(...)
нотацию, если вы предпочитаете), весь список имен, созданных имfind
, вставляется обратно в командную строку в качестве аргументовtar
, в результате чего он записывает их все сразу.источник
find
редко рекомендуется использовать стандартный вывод . mywiki.wooledge.org/ParsingLsread -r
из-print0
), как я сделал в своем ответе.Вопрос 1
Ваша команда терпит неудачу, потому что
tar
берет каждый из найденных файлов и архивирует ихfile.tar
. Каждый раз, когда это происходит, он перезаписывает ранее созданныйfile.tar
.Если вам нужен один архив со всеми файлами, то просто запустите
tar
напрямую, в этом нет необходимостиfind
(и да, это работает для файлов с пробелами в их именах):вопрос 2
Две команды совершенно разные:
find var / log будет искать каталог с именем,
var/log
который является подкаталогом вашего текущего каталога , он эквивалентенfind ./var/log
(обратите внимание на./
).найти / вар / журнал будет искать каталог с именем ,
/var/log
который является подкаталогом корня/
.Ведущее
/
сообщение отtar
, а неfind
. Это означает, что он удаляет первое/
из ваших имен файлов, чтобы превратить абсолютные пути в относительные . Это означает, что файл из/var/log/anaconda.error
будет извлечен,./var/log/anaconda.error
когда вы распакуете архив.источник
Есть два способа
-exec
работы. Один способ запускает команду много раз - один раз для каждого файла; другой способ запускает команду один раз, включая все файлы в виде списка параметров.-exec tar -cvf file.tar {} ';'
запускаетtar
команду для каждого файла, каждый раз перезаписывая архив.-exec tar -cvf file.tar {} '+'
запускаетtar
команду один раз, создавая архив всех найденных файлов.источник
Я думаю, что использование -exec для каждого файла может сделать сжатие tar очень медленным, если у вас много файлов. Я предпочитаю использовать команду:
источник
/bin/cpio: xxx: Cannot open: Too many open files