Удаление новых строк из файла RTF с помощью sed

3283
MoshiBin

У меня есть файл RTF, который отформатирован так:

 Lorem ipsum dolor sit amet, consectetur adipiscing elit.\par Nullam vitae sem porttitor urna pellentesque gravida. Nulla\par consequat purus vel est vehicula porttitor.\par Maecenas pharetra metus in enim sollicitudin sollicitudin.\par Etiam et odio tellus, eget placerat enim. Aliquam sem purus,\par gravida sed feugiat eget, consectetur quis nisl.\par 

(\ par добавлено для краткости)

Как видите, новые строки вставлены по ширине страницы. Проблема возникает, когда я пытаюсь прочитать текст на моем iPhone, который имеет другую длину строки. Разрыв строк и читаемость затруднены.

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

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

Есть ли лучшее решение для этого? Если нет, то как я могу сделать это с помощью sed?

2

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

3
MoshiBin

Решение лежало в инструменте, о котором я не задумывался серьезно - awk

awk 'BEGIN { FS="\\\\par" } ; /^ / /^[^ ]/ ' 

Это будет проходить по файлу, с \ par в качестве разделителя полей, и будет печатать \ par перед любой строкой, начинающейся с 4 пробелов (которая отмечает начало нового абзаца), и удалит (или просто не будет печатать) это когда он начинается с чего-либо, кроме пробела.

Теперь у нас есть файл с \ par только там, где должны быть допустимые разрывы строк. Следующим шагом будет полное удаление всех новых строк, чтобы избавиться от мошеннических разрывов строк:

tr -d '\r\n' 

А затем передайте результат в sed, чтобы заменить \ par на \ par \ r \ n, практически добавив новую строку, где находится \ par.

sed 's/\\par/\\par\r\n/g' 

И сделано.

Единственная проблема, с которой я столкнулся при использовании этого метода, заключается в том, что он испортил заголовок RTF. Нет проблем, я просто скопировал поверх заголовка из исходного файла.

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

ГЛАВА ТРИДЦАТЬ ВТОРАЯ
Название главы

Поэтому быстрый сед позаботился о них:

sed 's/\s*\(CHAPTER [[:upper:]-]* \)\(.*\\par\)/\\par\r\n\\par\r\n\\par\r\n\1\\par\r\n\2\\par\r\n/' 

Теперь у меня есть книга в правильном формате, что позволяет читать ее на других устройствах (например, на моем iPod).

2
Peter Boughton

Это регулярное выражение будет соответствовать тому, что вы хотите:

\r\n(?! ) 


Итак, чтобы использовать это с sed:

sed 's/\r\n(?! )/ /g' filename.rtf 


За исключением того, что, похоже, sed не поддерживает отрицательный прогноз, и ему необходимо использовать символы обратной косой черты, поэтому вместо этого вы можете использовать:

sed 's/\r\n\([^ ]\)/ \1/g' filename.rtf 
sed работает, читая по одной строке за раз. \ r \ n не совпадает MoshiBin 15 лет назад 0
Хм, тогда используйте инструмент, который работает на весь файл сразу, то Peter Boughton 15 лет назад 0
Или вот возможное решение для многострочного с sed: http://www.ilfilosofo.com/blog/2008/04/26/sed-multi-line-search-and-replace/ Peter Boughton 15 лет назад 0

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