Мой текстовый файл выглядит так:
This is one
sentence that is broken.
However this is a good one.
And this
one is
somehow, broken into
many.
Я хочу удалить завершающий символ новой строки для любой строки, за которой следует строка, начинающаяся со строчной буквы.
Так что это должно быть:
This is one sentence that is broken.
However this is a good one.
And this one is somehow, broken into many.
Как я могу это сделать?
Изменить: Здесь есть несколько действительно хороших ответов, но я решил принять первый, который работал и был самым ранним. Большое спасибо всем!
Ответы:
пытаться
где
$NF !~ /\.$/
строка соответствия, где последний элемент не заканчивается точкой,{ printf "%s ",$0
напечатать эту строку с пробелом, без перевода строки,next ; }
получить следующую строку,{print;}
и распечатай это.Я уверен, что будет
sed
вариант.Примечание: это будет работать со строкой, заканчивающейся точкой, однако условие в предложениях, начинающихся с заглавной буквы, не будет объединено. Смотрите ответ Стефана Шазеля.
источник
awk 'ORS=$NF~/\.$/?"\n":" "'
С
awk
:То есть не добавляйте разделитель записей в каждую строку (ORS пуст). Но добавьте разделитель записей перед текущей строкой, если не в первой строке, и текущая строка не начинается со строчной буквы. В противном случае вместо этого добавьте пробел, кроме первой строки.
источник
And thisone issomehow, broken intomany.
я не знаю,awk
но нужно ли соединять строки<space>
в дополнение кRS
? Или это ошибка пользователя?В Perl:
Технически вы хотели заменить «символ новой строки с последующей строчной буквой» на «пробел и строчная буква», что и делает ядро приведенного выше сценария perl:
input
.input
переменную, чтобы она стала результатом операции поиска и замены.источник
perl -0777 -pe 's/\n([a-z])/ $1/g'
и может быть аналогичным образом выполнено с помощью GNU sed какsed -zE 's/\n([a-z])/ \1/g'
(при условии, что ввод не имеет нулевых символов)perl -Mopen=locale -0777 -pe 's/\n(?=[[:lower:]])/ /g'
чтобы он не ограничивался буквами ASCII.С помощью
sed
вы можете использоватьN;P;D
цикл (чтобы всегда иметь две строки в шаблонном пространстве, и если первый символ после новой строки строчный, то заменить новую строку пробелом) иt
est - таким образом, после каждойs
замены вы перезапускаете цикл:источник
N;P;D
цикл, поэтому я не буду его повторять. Разница здесь вt
том, что самое главное - проверить, было ли что-то заменено или нет - если тест пройден успешно, мы переходим к началу скрипта, иначе это означает, что ничего не было заменено иP;D
выполнено. Дайте мне знать, если это все еще неясно.Использование
sed
иfmt
:Сценарий sed вставляет новую строку перед каждой строкой, которая начинается с заглавной буквы (за исключением самой первой строки ввода).
sed
Затем выводитсяfmt
результат, чтобы переформатировать результирующие абзацы.В качестве альтернативы используйте,
par
если он у вас установлен. Это еще одно средство переформатирования абзацев, но гораздо более функциональное, чемfmt
с множеством других функций и опций.Обратите внимание, что между каждым абзацем будет пустая строка. Параграфы должны быть отделены друг от друга хотя бы одной пустой строкой. Без пустых строк весь ваш входной образец переформатируется как один абзац из нескольких предложений, например:
Если вам нужно удалить пустые строки после переформатирования, просто передайте их
sed
снова, но это удалит ВСЕ пустые строки, включая те, которые могли быть в исходном вводе. напримеристочник
Еще один способ сделать это:
где:
$\
=>ORS
,$/
=>IRS
=\n
,$"
=space
источник
Python 3
Это то же регулярное выражение / замена, что и ответ Джеффа
источник