2017-01-23 9 views
-2

Я пытаюсь искать pdf-файлы с терминала. Моя попытка - предоставить строку поиска из терминала. Строкой поиска может быть одно слово, несколько слов с (И, ИЛИ) или точная фраза. Я хотел бы оставить только один параметр для всех поисковых запросов. Я сохраню следующую команду в качестве сценария оболочки и вызову сценарий оболочки как псевдоним из .aliases в оболочке zsh или bash.Один параметр для нескольких шаблонов - grep

Следуя от ответа sjr, здесь: search multiple pdf files.

Я использовал ответ SJR как это:

find ${1} -name '*.pdf' -exec sh -c 'pdftotext "{}" - | 
     grep -E -m'${2}' --line-buffered --label="{}" '"${3}"' '${4}'' \; 

$1 принимает тракту

$2 ограничивает количество результатов

$3 является параметр контекста (он принимает -A, -B , -C, индивидуально или совместно)

$4 принимает поисковый запрос g

Вопрос, с которым я столкнулся, имеет значение $4. Как я сказал ранее, я хочу, чтобы этот параметр передавал мою строку поиска, которая может быть фразой или одним словом или несколькими словами с отношением AND/OR.

Я не могу получить желаемые результаты, до сих пор я не получал результаты поиска для поиска фразы, пока не последовал за комментарием Робин Грина. Но все же фразовые результаты неточны.

Редактировать Текст из суждений:

The original rule was that you could not claim for psychiatric injury in 
negligence. There was no liability for psychiatric injury unless there was also 
physical injury (Victorian Rly Commrs v Coultas [1888]). The courts were worried 
both about fraudulent claims and that if they allowed claims, the floodgates would 
open. 

The claimant was 15 metres away behind a tram and did not see the accident but 
later saw blood on the road. She suffered nervous shock and had a miscarriage. She 
sued for negligence. The court held that it was not reasonably foreseeable that 
someone so far away would suffer shock and no duty of care was owed. 

White v Chief Constable of South Yorkshire [1998] The claimants were police 
officers who all had some part in helping victims at Hillsborough and suffered 
psychiatric injury. The House of Lords held that rescuers did not have a special 
position and had to follow the normal rules for primary and secondary victims. 
They were not in physical danger and not therefore primary victims. Neither could 
they establish they had a close relationship with the injured so failed as 
secondary victims. It is necessary to define `nervous shock' which is the rather 
quaint term still sometimes used by lawyers for various kinds of 
psychiatric injury...rest of para 

word1 может быть: шок, (нервный шок)

word2 может быть: психиатрическое

exact phrase: (нервная шок)

Команды

alias s='sh /path/shell/script.sh' 
export p='path/pdf/files' 

В терминале:

s "$p" 10 -5 "word1/|word2"   #for OR search 
s "$p" 10 -5 "word1.*word2.*word3" #for AND search 
s "$p" 10 -5 ""exact phrase""  #for phrase search 

Второе испытание образца: PDF пример файла, так как команда запускает на документ в формате PDF: Test-File. Его 4 страницы (часть 361 пг файла)

Если мы запустим следующую команду на ней, как решение упоминает:

s "$p" 10 -5 'doctrine of basic structure' > ~/desktop/BSD.txt && open ~/desktop/BSD.txt

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

+1

Почему нижний предел? хочу знать, чтобы я мог заботиться в будущем, задавая вопросы. – lawsome

+2

Одиночные кавычки приведут к тому, что цитируемые параметры не будут расширены (если вы используете bash или sh), чего вы не хотите. Вы должны использовать двойные кавычки для цитирования параметров в bash или sh. Или вы используете другую оболочку? –

+1

Я не проголосовал, и я тоже хочу, чтобы люди оставили отзыв, когда они это делают. Тем не менее, всегда стоит уменьшить ваш вопрос до [MCVE (минимальный, полный и проверенный пример)] (http://stackoverflow.com/help/mcve). Общие советы по заданию вопроса можно найти здесь (http://stackoverflow.com/help/how-to-ask). – mklement0

ответ

1

Вам нужно:

  • передать строку в двойных кавычках команды для sh -c, чтобы для встроенной оболочки переменной ссылки будет расширен (который затем требует спасаясь встроенные" экземпляры как \").

  • цитаты регулярное выражение с printf %q для безопасного включения в командной строке - обратите внимание, что это требует bash, ksh или zsh в качестве оболочки.

dir=$1 
numMatches=$2 
context=$3 
regexQuoted=$(printf %q "$4") 

find "${dir}" -type f -name '*.pdf' -exec sh -c "pdftotext \"{}\" - | 
    grep -E -m${numMatches} --with-filename --label=\"{}\" ${context} ${regexQuoted}" \; 

В 3 сценарии Призыва бы тогда:

s "$p" 10 -5 'word1|word2'   #for OR search 
s "$p" 10 -5 'word1.*word2.*word3' #for AND search 
s "$p" 10 -5 'exact phrase'   #for phrase search 

Обратите внимание, что нет никакой необходимости, чтобы избежать | и нет необходимости добавлять дополнительный слой двойных кавычек вокруг exact phrase.

Также обратите внимание, что я заменил --line-buffered на --with-filename, так как я предполагаю, что это то, что вы имели в виду (чтобы иметь соответствующие строки с префиксом пути к файлу PDF).


Обратите внимание, что с вышеизложенным подходом экземпляр оболочки должен быть создан для каждого входного тракта, что является неэффективным, поэтому следует переписывать команду следующим образом, что также исключает необходимость printf %q (предположит regex=$4):

find "${dir}" -type f -name '*.pdf' | 
    while IFS= read -r file; do 
    pdftotext "$f" - | 
     grep -E -m${numMatches} --with-filename --label="$f" ${context} "${regex}" 
    done 

выше предполагает, что ваши имена файлов не имеют встроенные символы новой строки, которая редко реального мира беспокойство. Если да, то есть способы решить проблему.

Дополнительное преимущество этого решения заключается в том, что он использует только POSIX-совместимые оболочек функции, но учтите, что команда grep использует нестандартные варианты.