2015-03-24 5 views
0

Я создаю скрипт, который должен искать внутри всех PDF-файлов в каталоге. Я нашел один преобразованный под названием «pdftotext», который позволяет мне использовать grep для файлов pef, но я могу запустить его только с одним файлом. Когда я хочу запустить его по всем файлам, находящимся в каталоге, это не сработает. Какие-либо предложения ?Как связать xargs с конвертером pdftotext для поиска внутри нескольких файлов PDF

Это работает: для одного файла

pdftotext my_file.pdf - | grep 'hot' 

Это не удается: для поиска PDF-файлов и преобразование в текст и greping

SHELL PROMPT>find ~/.personal/tips -type f -iname "*" | grep -i "*.pdf" | xargs pdftotext |grep admin 
pdftotext version 3.00 
Copyright 1996-2004 Glyph & Cog, LLC 
Usage: pdftotext [options] <PDF-file> [<text-file>] 
    -f <int>   : first page to convert 
    -l <int>   : last page to convert 
    -layout   : maintain original physical layout 
    -raw    : keep strings in content stream order 
    -htmlmeta   : generate a simple HTML file, including the meta information 
    -enc <string>  : output text encoding name 
    -eol <string>  : output end-of-line convention (unix, dos, or mac) 
    -nopgbrk   : don't insert page breaks between pages 
    -opw <string>  : owner password (for encrypted files) 
    -upw <string>  : user password (for encrypted files) 
    -q    : don't print any messages or errors 
    -cfg <string>  : configuration file to use in place of .xpdfrc 
    -v    : print copyright and version info 
    -h    : print usage information 
    -help    : print usage information 
    --help   : print usage information 
    -?    : print usage information 
SHELL PROMPT 139> 

ответ

1

xargs неправильный инструмент для этой работы: find делает все вам нужен встроенный.

find ~/.personal/tips \ 
    -type f \ 
    -iname "*.pdf" \ 
    -exec pdftotext '{}' - ';' \ 
    | grep hot 

Это сказало, если вы сделал хотите использовать xargs по какой-то причине, правильное использование будет выглядеть примерно так ...

find ~/.personal/tips \ 
    -type f \ 
    -iname "*.pdf" \ 
    -print0 \ 
    | xargs -0 -J % -n 1 pdftotext % - \ 
    | grep hot 

Обратите внимание, что:

  • Команда find использует -print0 для NUL-delimit его вывод
  • Команда xargs использует -0 для NUL-разграничивает свой вход (что также отключает некоторое поведение, которое приведет к некорректной обработке имен файлов с пробелами в их именах, символах буквенных кавычек и т. д.).
  • Команда xargs использует -n 1 для вызова pdftotext один раз в файл
  • Команда xargs использует -J % указать сигилу для того, где замена должна произойти, и использует % в командной строке pdftotext соответствующим образом.
+0

спасибо за отзыв, это сработало хорошо для меня. –

2
find . -name '*.pdf' -print0 | xargs -0 -n1 -I '{}' pdftotext '{}' - 

По умолчанию, xargs будет пытаться соответствовать столько строк в командной строке для pdftotext, насколько это возможно. Вы этого не хотите. Что вы хотите - это один файл за вызов, за которым следует '-'. Это можно сделать с помощью -n1 (ограничение на один аргумент за вызов) и -I '{}' (make {} будет заполнителем, где будет соответствовать аргумент).

Опция -print0, которую можно найти в сочетании с параметрами -0, для xargs позволяет использовать '\ 0' (null bytes) вместо новых строк ('\ n') в качестве разделителей аргументов.

Xargs с -n1 и -I{} Используемый как это в значительной степени семантически эквивалентен find -exec, как рекомендовал Чарльз Даффи. Преимущество Xargs заключается в том, что он может использовать многоядерные процессоры (он может одновременно запускать несколько экземпляров pdftotext, вы можете настроить количество с помощью переключателя -P).

+0

Я становлюсь ниже ошибки SHELL PROMPT> найти ~/.личный/tips/pdf -name '*.pdf '-print0 | xargs -0 -n1 -I {} pdftotext {} - xargs: {}: Нет такого файла или каталога –

+1

Возможно, стоит цитировать '{}', если кто-либо читает этот ответ, использует zsh. (Вот почему я придерживаюсь '%', предложенного на странице man xargs, я сам не использую zsh, но не имею причины создавать режим отказа для других людей, используя основную оболочку). –

+2

BTW, в то время как вывод 'find' может отображать все имена файлов, кроме символов с символами новой строки, без использования' -print0', поведение по умолчанию, используемое 'xargs' для чтения содержимого, не столь устойчиво без' -0'; он пытается интерпретировать цитаты, анализировать пробелы и т. п .; это не прямой эквивалент с заменой newlines-vs-NULL. Использование расширения GNU xargs '-d $ '\ n'' является разумным, если использовать xargs для чтения имен строк с разделителями строк, поскольку это отключает другие поведения. –