Извлечь строки между тегами и сохранить в новый текстовый файл

Мне нужно извлечь текстовые строки из файла и поместить их в новый файл. Каждая строка всегда находится между одним и тем же текстом (тегами).

Вот пример (есть сотни таких блоков, где мне нужно поместить данные в один файл):

1731 0 obj
<>
endobj

Мне нужно извлечь Page 250 и ПРИМЕР ТЕКСТ ДЛЯ ИЗВЛЕЧЕНИЯ

Для примера Page 250 релевантными тегами выглядят:

<

и

/Type

Для ПРИМЕР ИЗВЛЕЧЕНИЯ ТЕКСТА , например, соответствующие теги выглядят так:

/Contents(

и

)/F

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

Я попытался использовать некоторые ответы из здесь , но мне не удалось заставить его работать ...

Мне удобнее всего работать с командной строкой Unix, но я немного знаю Python и AppleScript

0
13.04.2017, 15:36
2 ответа

Я добавил ваш пример содержимого в файл на диске с именем файл , а затем показал содержимое файла с помощью команды cat . Затем, используя awk в файле , я вырезаю части, которые вы вызываете тегами , и распечатываю две части данных в формат с разделителями табуляции. Это то, что вы ищете?

$ cat file
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj
$ awk '{sub(/\<\<\//, "")};{sub(/\/Type.*\/Contents\(/, "\t")};{sub(/\)\/F.*$/, "")};/Page [0-9]/{print}' file
Page 250    EXAMPLE OF TEXT TO BE EXTRACTED
$

Что делает программа awk :

  • / Page [0-9] / ищет строки, содержащие, т.е. , «Страница» - пробел, за которым следует число, например, Page 250 . Я предполагаю, что ПРИМЕР ИЗВЛЕЧЕННОГО ТЕКСТА не будет содержать этого шаблона. Не то чтобы я думаю, что это имеет значение, хотя код можно легко изменить, чтобы приспособиться к этому.

  • sub (/ \ <\ <\ //, "") полосы: << /

  • sub (/ \ / Type. * \ / Contents \ (/, "\ t" ) заменяет все между / Type и / Contents ( табуляцией.
  • sub (/ \) \ / F. * $ /, "") удаляет все от ) / F до конца строки.

Итак, что осталось, это то, что распечатано. Две части требуемых данных , разделенных табуляцией.

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

Так что, если бы вы могли прояснить ситуацию, я, вероятно, мог бы написать сценарий bash , чтобы покрыть это.

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

1
28.01.2020, 02:34

С awk :

awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) \
         if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
  • Установка разделителя полей как / , если первое поле ] << , затем сохранение второго поля как переменной i для печати позже

  • Итерация по остальным полям, и если какое-либо поле начинается с Contents , то разделение поля на () для создания массива a , для (j = 3; j <= NF; j ++) if ($ j ~ / ^ Contents /) split ($ j, a, "[()]")

  • выводит переменную i и второй элемент массива a , разделяя их _

Пример:

% cat file.txt                                                                                                        
1731 0 obj
<</Page 250/Type/Annot/Subtype/Highlight/Rotate 0/Rect[ 95.4715 347.644 337.068 362.041]/NM(929cd95c-f962-4fa3-b734-2e0e67d7b321)/T(iPad)/CreationDate(D:20160818145053Z00'00')/M(D:20160818145204Z00'00')/C[ 0.454902 0.501961 0.988235]/CA 1/QuadPoints[ 95.4715 362.041 337.068 362.041 95.4715 347.644 337.068 347.644]/Contents(EXAMPLE OF TEXT TO BE EXTRACTED)/F 4/Subj(Highlight)>>
endobj

% awk -F/ '$1=="<<" {i=$2; for(j=3;j<=NF;j++) if($j~/^Contents/) split($j,a,"[()]"); print i " _ " a[2]}' file.txt
Page 250 _ EXAMPLE OF TEXT TO BE EXTRACTED
1
28.01.2020, 02:34

Теги

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