LINUX.ORG.RU

\n и sed/perl

 


0

1

Нужно написать скрипт на bash, который бы переводил новое предложение на новую строку. С основной задачей справился - теперь после точки и пробела ставится \n. Однако, в тексте встречаются такие вещи, как «par. 24.4. of the Regulations*», где перед «of the Regulations*» ставится \n, хотя делать этого не нужно. Написал костыль в виде

perl -p -e 's/\n\of/of/g' "$file" > "$tmpfile"
но он почему-то не срабатывает. Sed вообще не справляется с конструкциями с \n, если \n стоит в заменяемой части. Почему? Что следует написать вместо указанной выше команды? Или, возможно, вся задача решается гораздо проще?

Deleted

но он почему-то не срабатывает.

да потому, что в данном случае регексп будет применяться к каждой строке отдельно, а не ко всему тексту, и символ новой строки будет её последним символом. т.е. ты обработаешь строки «…par. 24.4. \n» и «of the Regulations…» отдельно. чтобы обработать весь текст целиком одним регекспом, нужно убрать символ-разделитель строк:

perl -pe 'BEGIN{$/=undef}s/\nof/of/g'

а вообще просто правильно разбивай на строки :)

arsi ★★★★★
()
Ответ на: комментарий от derlafff

$1 позволяет вернуть первую букву?

sed -i 's/\. \([A-Z]\)/\.\n\$1/g' "/tmp/1"
просто удаляет первую букву и выводит вместо нее '$1'
perl -p -e 's/. \([A-Z]\)/. \n$1/g' < "/tmp/0" > "/tmp/1"
\n не ставит.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Ответ на: комментарий от Deleted

Вместо $1 нужно \1, да

Оно должно возвратить то, что в \(\)

% echo '123. A' | sed -e 's/. \([A-Z]\)/.\n\1/g'
123.
A
% echo '123. a' | sed -e 's/. \([A-Z]\)/.\n\1/g'
123. a

Т.е. срабатывание по заглавной букве после точки.

Как там в перле - не знаю, только в sed умею.

У arsi сверху вариант таки лучше, ибо не только точка, но и ? и !. В остальном не понятно, что лучше

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 5)

«par. 24.4. of the Regulations*», где перед «of the Regulations*» ставится \n, хотя делать этого не нужно.

В PCRE можно отловить точку, за которой следует пробел и заглавная буква через unicode character properties, не знаю, как на perl, а в php я бы сделал так

~(\.) (?= \s\pLu)~ux
Будет работать с кириллицей и другими нелатинскими алфавитами.

Deleted
()
Ответ на: комментарий от Deleted

> unicode character properties

> не знаю, как на perl

perl -CSD -pe 's/(?<=[.!?])\s+(?=\p{Uppercase})/\n/g'
arsi ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.