Вы также можете использовать менеджеры плагинов, такие как:
попробуй
awk '$NF !~ /\.$/ { printf "%s ",$0 ; next ; } {print;}' file
где
$NF !~ /\.$/
строка совпадения, где последний элемент не заканчивается точкой, { printf "%s ",$0
напечатать эту строку с пробелом в конце и без перевода строки, next ; }
выбрать следующую строку, {print;}
и распечатайте его. Я уверен, что будет вариант sed
.
Обратите внимание, :это будет работать со строкой, заканчивающейся точкой, однако условие в предложениях, начинающихся с заглавной буквы, не будет объединено. Смотрите ответ Стефана Шазеласа.
В перле:
#!/usr/bin/perl -w
use strict;
my $input = join("", <>);
$input =~ s/\n([a-z])/ $1/g;
print $input;
Технически вы хотели заменить «новую строку, за которой следует буква нижнего регистра -» на «пробел и -эту букву -нижнего -регистра -», что и является ядром приведенного выше perl. скрипт делает:
input
. input
, чтобы она стала результатом операции поиска и замены. С помощью sed
вы можете использовать N;P;D
цикл (, чтобы всегда иметь две строки в пространстве шаблона, и если первый символ после новой строки в нижнем регистре, то заменить новую строку пробелом )и a t
есть -таким образом после каждой s
замены вы перезапускаете цикл:
sed -e :t -e '$!N;/\n[[:lower:]]/s/\n/ /;tt' -e 'P;D' infile
Другой способ сделать это:
perl -lpe '$\ = /\.$/ ? $/ : $"' data
где:$\
=> ORS
, $/
=> IRS
= \n
, $"
=space
perl -pe '$_.= <>, eof or redo if s/[^.]\K\n/ /' data
sed -e '
:a
/\.$/!N
s/\n/ /
ta
' data
Сawk
:
awk -v ORS= '{print (NR == 1 ? "" : /^[[:lower:]]/ ? " " : RS) $0}
END {if (NR) print RS}'
То есть не добавлять разделитель записей к каждой строке (ORS пусто ). Но добавьте разделитель записей перед текущей строкой, если он не находится в первой строке и текущая строка не начинается с буквы нижнего регистра. В противном случае вместо этого добавьте пробел, за исключением первой строки.
import re
print(re.sub(r'\n([a-z])', r' \1', open('file.txt').read(), flags=re.MULTILINE))
Это то же регулярное выражение/подстановка, что и ответ Джеффа
Использование sed
иfmt
:
$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
Сценарий sed вставляет новую строку перед каждой строкой, начинающейся с заглавной буквы (, за исключением самой первой строки ввода ). Вывод sed
затем передается в fmt
для переформатирования результирующих абзацев.
В качестве альтернативы используйте par
, если он у вас установлен. Это еще одно преобразование абзаца, но гораздо более функциональное, чем fmt
, с большим количеством функций и опций.
Обратите внимание, что между каждым абзацем будет пустая строка. Абзацы должны отделяться друг от друга хотя бы одной пустой строкой. Без пустых строк весь ваш входной образец переформатируется как один абзац из нескольких -предложений, например.:
$ fmt input.txt
This is one sentence that is broken. However this is a good one.
And this one is somehow, broken into many.
Если вам нужно удалить пустые строки после переформатирования, просто передайте их через sed
снова -, но это удалит ВСЕ пустые строки, включая те, которые могли быть в исходном вводе. например.
$ sed -e '1n; s/^[[:upper:]]/\n&/' input.txt | fmt | sed -e '/^$/d'
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.