Поиск строки внутри pdf с pdfgrep и выводит только имя файла

983
FXux

Я использую pdfgrep для поиска имени в PDF:

pdfgrep -H 'Fatima Alves' RE/* 

Эти команды выведут имя файла и имя:

RE/2011-01-RE_60822079000168_23022016_153923(1).PDF: Fatima Alves  RE/2011-01-RE_60822079000168_23022016_153923 (2).PDF: Fatima Alves 

Но я хотел бы напечатать только имя файла, без : Fatima Alves

Потому что я хотел бы использовать канал с XARGS для перемещения файлов соответствия:

pdfgrep -H 'Fatima Alves' RE/* | xargs -I{} mv -i {} ./destination 

Но в текущей ситуации перемещение не работает, потому что пытается переместить файл, который не существует:

mv: cannot stat ‘RE/2011-01-RE_60822079000168_23022016_153923(1).PDF: Fatima Alves’: No such file or directory mv: cannot stat ‘RE/2011-01-RE_60822079000168_23022016_153923 (2).PDF: Fatima Alves’: No such file or directory 

Благодарю.

-2
-H печатает имена файлов и: Фатима Алвес в финале. FXux 8 лет назад 0

2 ответа на вопрос

0
l0b0

You can modify the pdfgrep output like follows to make it usable in xargs:

$ echo 'RE/2011-01-RE_60822079000168_23022016_153923(1).PDF: Fatima Alves' | grep --perl-regexp --only-matching '.*(?=: Fatima Alves$)' RE/2011-01-RE_60822079000168_23022016_153923(1).PDF 

So for any given regular expression and pdfgrep output, you can do this:

regex='Fatima Alves' pdfgrep -H "$regex" RE/* | grep --perl-regexp --only-matching ".*(?=: $regex\$)" 

Edit:

I originally thought only the matching part of the line was printed by pdfgrep. Since it prints the whole line we have to simply remove everything including and following the colon separator:

pdfgrep -H "$regex" RE/* | sed 's/:.*//' 
PDF бинарные, я не могу использовать только grep, мне нужно использовать pdfgrep: / FXux 8 лет назад 0
Обновлено, чтобы уточнить. l0b0 8 лет назад 1
Привет @ l0b0, большое спасибо за ответ! Я с трудом. Проверьте вывод: http://i.imgur.com/qxYHDP8.png FXux 8 лет назад 0
Мы почти на месте, это вывод: http://i.imgur.com/moNYxG2.png Ошибка «mv: not stat» происходит из-за пробелов в имени, верно? добавив -0 к xargs: | xargs -0 решит (если я прав), теперь у нас есть еще одна проблема, команда застряла в первом файле, как бесконечный цикл, вы знаете почему? FXux 8 лет назад 0
@ FátimaAlves Нет, вероятно, выдает ошибки, потому что некоторые файлы были перемещены уже в какой-то момент. Вывод `pdfgrep` должен быть уже отсортирован, так как наиболее вероятные файлы обрабатываются в том же порядке, в который расширяется глобус` RE / * `, поэтому простая передача вывода в` uniq` сначала должна исправить это: `pdfgrep -H" $ регулярное выражение "RE / * | grep --perl-regexp --only-match ". * (? =: $ regex \ $)" | uniq | [...] `. @ l0b0, я бы не одобрил решение `sed`, так как имена файлов, содержащие двоеточия, разрешены в * nix. kos 8 лет назад 0
@kos До тех пор, пока нет способа узнать, является ли символ двоеточия частью имени файла, вы не можете надежно получить 100% -ное решение этой проблемы, поэтому я собираюсь найти 99% -ное решение. И вы должны `sort -u` в случае, если по какой-либо причине` pdfgrep` может выводить строки в искаженной последовательности. l0b0 8 лет назад 0
Решение "grep" на 100% безопасно. И на самом деле вы можете иметь 100% безопасное решение с помощью `sed`:` pdfgrep -H "$ regex" RE / * | sed 's / \ (. * \):. * / \ 1 /' `. kos 8 лет назад 0
Работают ребята !!!! Большое спасибо!!! FXux 8 лет назад 0
@kos, мы не можем изменить это регулярное выражение, чтобы избежать всего до последнего: ?? Я пытаюсь как javascript (со знаком?): Sed 's / \ (. *? \):. * / \ 1 /', но не работает. FXux 8 лет назад 0
@ FátimaAlves Я не понимаю, что именно ты пытаешься сделать. "Избегать всего до последнего`: `", как в "Отменить все до последнего`: `" (т.е. печатать только то, что следует за последним `:`)? kos 8 лет назад 0
Опс, извините .. я имею в виду "Совпадение всего до первого:" хахахаха FXux 8 лет назад 0
В текущей ситуации регулярное выражение сопоставляет все до последнего: и кое-что, что мне нужно, ловит документы за час, например 22:00:00, это было бы проблемой. FXux 8 лет назад 0
@ FátimaAlves: Когда вы говорите «хахахаха», кажется, что вы шутите, и что вы не серьезно относитесь к получению ответа на свой вопрос. Если люди поверит в это, они почувствуют, что вы напрасно тратите наше время, и они могут больше не захотеть вам помогать. Scott 8 лет назад 0
Спасибо за действительно хороший совет, профессор .. ХАХАХАХХАХАХАХАХ FXux 8 лет назад 0
0
evadeflow

Я считаю, что проще всего создать команду постепенно. Вы можете получить список подходящих имен файлов, используя:

$ pdfgrep -i "Fatima Alves" *.pdf | cut -d: -f1 | sort -u 

Запустив указанную выше команду и убедившись, что она генерирует ожидаемый результат, вы можете использовать команду подстановки Bash ( $()) и раскрытие истории ( !!), чтобы быстро перезапустить ее и переместить файлы, например, так:

$ mv $(!!) ./destination 

Конечно, вместо этого вы можете повторно ввести всю команду, если вы предпочитаете:

$ mv -i $(pdfgrep -i "Fatima Alves" *.pdf | cut -d: -f1 | sort -u) ./destination 

Обратите внимание, что это не удастся при двух обстоятельствах:

  1. Патологический случай, когда ни один файл не соответствует шаблону, приведет к несколько загадочной ошибке: mv: missing destination file operand after './destination'
  2. Файлы с пробелами в имени будут вызывать проблемы.

Лично я не удосужился найти обходной путь для этих двух режимов сбоев, потому что я всегда запускаю такие команды «матч + действие» в два этапа (поэтому я всегда знаю, было ли совпадений ноль, и поэтому действие можно пропустить) и Я старательно избегаю имен файлов с пробелами в них. Но при необходимости вы можете добавить что-то вроде | sed 's/ /\\ /gконца конвейера подстановки команд, чтобы избежать пробелов.

Похожие вопросы