как да свържете xargs с pdftotext конвертор за търсене в множество pdf файлове

Създавам скрипт, който трябва да търси във всички pdf файлове в директория. Намерих един конвертиран, наречен "pdftotext", който ми позволява да използвам grep на pef файлове, но мога да го стартирам само с един файл. Когато искам да го стартирам върху всички налични файлове в директорията, тогава той се проваля. Някакви предположения ?

Това работи: за един файл

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>

person Community    schedule 24.03.2015    source източник


Отговори (2)


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-ограничаване на своя изход
  • Командата xargs използва -0 за NUL-ограничаване на своя вход (което също така изключва някои действия, които биха довели до неправилно обработване на имена на файлове с интервали в имената им, буквални знаци в кавички и т.н.).
  • Командата xargs използва -n 1 за извикване на pdftotext веднъж на файл
  • Командата xargs използва -J %, за да посочи сигил за мястото, където трябва да се извърши замяната, и използва това % в командния ред pdftotext по подходящ начин.
person Charles Duffy    schedule 24.03.2015

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

По подразбиране xargs ще се опита да побере възможно най-много редове в командния ред за pdftotext. Ти не искаш това. Това, което искате, е един файл на извикване, последван от '-'. Това можете да постигнете с -n1 (ограничение до един аргумент на извикване) и -I '{}' (направете {} да бъде контейнер за мястото, където аргументът ще се побере).

Опцията -print0 за намиране, съчетана с опциите -0 на xargs, кара и двете да използват '\0' (нулеви байтове) вместо нов ред ('\n') като разделители на аргументи.

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

person PSkocik    schedule 24.03.2015
comment
Получавам по-долу грешка SHELL PROMPT›find ~/.personal/tips/pdf -name '*.pdf' -print0 | xargs -0 -n1 -I{} pdftotext {} - xargs: {}: Няма такъв файл или директория - person ; 24.03.2015
comment
Може би си струва да цитирате {} в случай, че някой, който чете този отговор, използва zsh. (Ето защо се придържам към %, предложен в страницата за справка на xargs; аз самият не използвам zsh, но няма причина да създавам режим на отказ за други хора, използващи основна обвивка). - person Charles Duffy; 24.03.2015
comment
Между другото, докато изходът на find може да представя точно всички имена на файлове с изключение на тези с нови редове, без да използва -print0, поведението по подразбиране, използвано от xargs за четене на съдържание, не е толкова стабилно без -0; опитва се да интерпретира кавички, да анализира интервали и други подобни; това не е прав еквивалент с размяна на нови редове срещу NULLs. Използването на разширението GNU xargs -d $'\n' е разумно, ако използвате xargs за четене на имена на файлове, разделени с нов ред, тъй като това деактивира другите поведения. - person Charles Duffy; 24.03.2015
comment
@Charles Duffy Добре е да знаете. Придържам се към -print0 (намиране) + -0 предимно (xargs), опитвайки се да се отклоня от онези тъмни ъглови случаи на обработка на командния ред на UNIX. - person PSkocik; 24.03.2015