Как найти, что строка нескольких выравнивает в сценарии оболочки?

Я хочу найти строку

Time series prediction with ensemble models

в PDF fle использующий сценарий оболочки. Я использую pdftotext "$file" - | grep "$string".where $file имя файла PDF и $string вышеупомянутая строка. Это может узнать строку, если вся строка содержит в line.but, это не может узнать строку как:

Time series prediction with 
ensemble models

как я могу разрешить его. Я плохо знаком с Linux. таким образом, объяснение подробно является appreciated.thanks заранее.

4
задан 11 September 2015 в 10:51

3 ответа

Другой подход, предложенный steeldriver в комментариях, должен заменить все разрывы строки пробелами, преобразовав вывод pdftotext в одну длинную линию и ища это:

string="Time series prediction with ensemble models"
pdftotext "$file" - | tr '\n' ' ' | grep -o "$string"

я добавил -o, чтобы заставить grep только распечатать подобранную часть строки. Без него Вы получили бы все содержание распечатанного файла.

<час>

Другой подход должен был бы использовать grep -z переключатель, который говорит ему использовать \0 вместо \n для определения строк. Это означает, что весь вход будут рассматривать как единственную "строку", и можно использовать Perl совместимые, или расширенные регулярные выражения для соответствия ему:

$ printf 'foo\nbar\nbaz\n' | grep -oPz 'foo\nbar'
foo
bar

Это, однако, не поможет, если Вы не будете знать перед рукой, как строка была разделена на несколько строк.

0
ответ дан 1 December 2019 в 09:35

Один возможный путь мог бы состоять в том, чтобы заменить grep pcregrep (доступный из репозитория 'вселенной'), который поддерживает многострочные соответствия, и затем вместо того, чтобы искать литеральную строку

Time series prediction with ensemble models

ищите вместо этого жемчуг совместимое регулярное выражение (PCRE)

Time\s+series\s+prediction\s+with\s+ensemble\s+models

где \s+ обозначает один или несколько пробельных символов (включая новые строки). Используя встроенные строковые возможности замены оболочки удара выполнить последний шаг

pdftotext "$file" - | pcregrep -M "${string// /\\s+}"

Если Вы не можете использовать pcregrep затем Вы смогли получать вывод, Вы хотите использовать плоскость grep с -z переключатель: это говорит grep считать вход "строками", которые будут разграничены NUL символы, а не новые строки - в этом случае, эффективно заставляя это рассматривать целый вход как одну строку. Так, например, если Вы только хотите распечатать соответствия (без контекста)

pdftotext "$file" - | grep -zPo "${string// /\\s+}"
4
ответ дан 1 December 2019 в 09:35

С Python много может быть сделано...

Если я посмотрю на него снова позже, то я, вероятно, смогу сделать некоторую оптимизацию, но в моих тестах, сценарий ниже делает задание.

Протестированный на файле:

Monkey eats banana since he ran out of peanuts 
Monkey
eats banana since he ran 
out of peanuts 
really, Monkey eats banana since 
he ran out of peanuts 
A lot of useless text here…
Have to add some lines for the sake of the test.
Monkey eats banana since he ran out of peanuts 

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

Found matches
--------------------
[line 1]
Monkey eats banana since he ran out of peanuts
[line 2]
Monkey
eats banana since he ran
out of peanuts
[line 5]
Monkey eats banana since
he ran out of peanuts
[line 9]
Monkey eats banana since he ran out of peanuts

Сценарий

#!/usr/bin/env python3
import subprocess
import sys

f = sys.argv[1]; string = sys.argv[2]

# convert to .txt with your suggestion
subprocess.call(["pdftotext", f])
# read the converted file
text = open(f.replace(".pdf", ".txt")).read()
# editing the file a bit for searching options / define th length of the searched string
subtext = text.replace("\n", " "); size = len(string)
# in a while loop, find the matching string and set the last found index as a start for the next match
matches = []; start = 0
while True:
    match = subtext.find(string, start)
    if match == -1:
        break
    else:
        matches.append(match)
    start = match+1

print("Found matches\n"+20*"-")
for m in matches:
    # print the found matches, replacing the edited- in spaces by (possibly) original \n
    print("[line "+str(text[:m].count("\n")+1)+"]\n"+text[m:m+size].strip())

Использовать его:

  1. скопируйте сценарий в пустой файл, сохраните его как search_pdf.py
  2. Выполните его командой:

    python3 /path/to/search_pdf.py /path/to/file.pdf string_to_look_for
    

Никакая потребность упомянуть Вас не должна использовать кавычки, если или путь или искавшая строка включают пробелы:

python3 '/path to/search_pdf.py' '/path to/file.pdf' 'string to look for'
1
ответ дан 1 December 2019 в 09:35

Другие вопросы по тегам:

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