Как вставить новую строку 3 пробела или 2 слова перед конкретным символом

Я пытался отформатировать журнал чата для друга, который выглядит так:

Джон Смит > привет, Джейн Доу > привет, как дела? Джон Смит > Довольно хорошо, спасибо

и она хочет отформатировать его так:

Джон Смит > привет

Джейн Доу > Привет, как дела?

Джон Смит > Довольно хорошо, спасибо

Просто ввести новую строку после > недостаточно, так как она будет неправильно форматироваться, поэтому мне нужно вставить новую строку 3 пробела или 2 слова перед «>», чтобы имя тоже было захвачено.

Пока у меня есть только новая строка после > :

/usr/bin/perl -p -i -e "s/>/>\n/g" *.txt

Изменить: задействовано более 20 различных имен чатов, поэтому было бы здорово сделать это, не вводя все их имена, поскольку они могут различаться, и я хотел бы извлечь уроки из этого упражнения для удовольствия. Спасибо за чтение


person Steve Martin    schedule 10.08.2010    source источник
comment
Это просто журнал обмена мгновенными сообщениями между двумя людьми? Есть довольно простой способ справиться со случаем, когда вы знаете имена пользователей в журнале.   -  person eldarerathis    schedule 10.08.2010
comment
Это групповой чат с 20 или около того разными именами, поэтому я старался не вводить все имена, так как они могут немного меняться в каждом сеансе. Это дрянной веб-интерфейс, который позволяет только выделять текст и копировать вставку, но не сохраняет форматирование...   -  person Steve Martin    schedule 10.08.2010
comment
Таким образом, имена пользователей всегда состоят из двух слов, с пробелом между двумя словами и еще одним пробелом между вторым словом и >?   -  person eldarerathis    schedule 10.08.2010
comment
Правильно, Имя Фамилия, а дальше как вы сказали. Спасибо   -  person Steve Martin    schedule 10.08.2010


Ответы (2)


Попробуй это:

perl -p -i -e "s/(\w+\s\w+\s*>)/\n\1/g" log.txt

Тест, который я использовал для регулярного выражения:

[21:21:23] ~ $ echo 'John Smith > hello Jane doe > hey how are you? John Smith > Pretty good thanks Susie Someone > hi guys' > log.txt
[21:21:24] ~ $ more log.txt 
John Smith > hello Jane doe > hey how are you? John Smith > Pretty good thanks Susie Someone > hi guys
[21:21:27] ~ $ perl -p -i -e "s/(\w+\s\w+\s>)/\n\1/g" log.txt
[21:21:34] ~ $ more log.txt 

John Smith > hello 
Jane doe > hey how are you? 
John Smith > Pretty good thanks 
Susie Someone > hi guys
[21:21:37] ~ $ 

Это добавляет дополнительную новую строку в начало файла, но если это вас не беспокоит, я думаю, что это должно работать.

Редактировать: также произойдет сбой, если кто-то по какой-то причине использовал символ > в одном из своих сообщений (в любом случае, если ему предшествовал пробел и два слова).

person eldarerathis    schedule 10.08.2010
comment
Да, в тех редких случаях, когда возникает какой-либо из этих сбоев, ручное редактирование будет в порядке, но лучше, чем она просматривает каждую строку и редактирует вручную! :) - person Steve Martin; 10.08.2010
comment
как насчет случаев, когда текст копируется? John Smith > Jane Doe > name/text by Jane Doe, copied/pasted by John Smith. Это просто появится как пустая строка Джона Смита, а затем Джейн Доу из предыдущего. Есть ли у вас возможность управлять приложением, создающим журнал? - person vol7ron; 10.08.2010
comment
Если вы не хотите, чтобы в начале была пустая строка, попробуйте следующее: perl -p -i -e "s/.(\b\w+\s\w+\s>)/\n\1/g" log.txt - person vol7ron; 10.08.2010

Я знаю, что у вас уже есть «достаточно хороший» сценарий. Но я все же решил предложить альтернативную стратегию.

Решите эту задачу в два этапа.

Часть первая: анализ необработанных данных и извлечение списка имен пользователей.

  • Ищите повторяющиеся группы слов (длиной до X), которые предшествуют >.
  • Создайте список возможных имен пользователей.

Здесь вмешивается человек и утверждает список имен пользователей.

Часть вторая: обработка данных на основе списка имен пользователей.

  • Обработайте файл и сопоставьте имена пользователей, чтобы использовать их в качестве разделителей.

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

Конечно, код будет более сложным. Стоит ли дополнительная сложность повышения точности, зависит от ваших потребностей.

person daotoad    schedule 10.08.2010