Если шаблон совпал, удалите символ новой строки в этой строке

Допустим, шаблон представляет собой строку «Любовь».

вход

This is some text
Love this or that
He is running like a rabbit

выход

This is some text
Love this or thatHe is running like a rabbit

Я заметил, что sed очень неприятно удаляет символы новой строки, есть идеи?


person josifoski    schedule 20.09.2014    source источник
comment
sed работает по одной строке за раз. Каждый раз, когда он начинает работать над строкой, он удаляет новую строку и помещает ее в пространство шаблона. Пространство паттерна — это место, где происходит все действие. Как только замена завершена, он помещает новую строку и печатает STDOUT. Чтобы удалить новую строку, вам нужно использовать N, которая добавляет следующую строку в пространство шаблона, разделенное \n, которое затем можно удалить с заменой.   -  person jaypal singh    schedule 20.09.2014
comment
Вам нравится пространство между that и He?   -  person Jotne    schedule 20.09.2014


Ответы (5)


Вы можете использовать это:

sed '/^Love/{N;s/\n//;}' love.txt

Детали:

/^Love/ определяет строку для обработки, если хотите, вместо нее можно использовать /[Ll]ove/

N добавляет следующую строку в пространство шаблонов. После этой команды пространство шаблонов содержит Love this or that\nHe is running like a rabbit

s/\n// заменяет символ новой строки

person Casimir et Hippolyte    schedule 20.09.2014
comment
только скажет вау, это легко объяснить, { } необходимы для использования ключевого элемента N @casimir-et-hippolyte - person josifoski; 20.09.2014
comment
@josifoski: в фигурных скобках заключены действия, которые необходимо выполнить, когда условие /^Love/ истинно. - person Casimir et Hippolyte; 20.09.2014
comment
Обратите внимание, что после первого совпадения и замены пространство шаблонов не будет содержать новую строку перед следующей строкой, которая была извлечена из-за N, и поэтому, если у вас был другой шаблон для сопоставления в начале следующей строки, он выиграл не совпадать. Например. рассмотрим, что происходит с входным файлом Love\nLove\nLove. Вторая Любовь никогда не совпадет. - person Some Guy; 15.12.2020
comment
@SomeGuy: sed ':a;/[Ll]ove[^\n]*$/{N;ba};s/\n//g' love.txt решает проблему с помощью простого цикла, добавляющего каждую последовательную совпадающую строку перед заменой (на этот раз глобальной). - person Casimir et Hippolyte; 16.12.2020

Перл:

$ perl -pe 's/^(Love[^\n]*)\n/\1/' file.txt
This is some text
Love this or thatHe is running like a rabbit

Или, если намерение сосредоточено исключительно на \n, вы можете chomp на основе шаблона:

$ perl -pe 'chomp if /^Love/' file.txt
This is some text
Love this or thatHe is running like a rabbit
person dawg    schedule 20.09.2014

$ awk '/Love/{printf "%s ",$0;next} 1' file
This is some text
Love this or that He is running like a rabbit

Объяснение:

  • /Love/{printf "%s ",$0;next}

    Для строк, содержащих Love, строка печатается через printf без новой строки. awk затем начинается заново со строки next.

  • 1

    Строки, не содержащие Love, печатаются как обычно (с новой строкой). Команда 1 является загадочным сокращением awk для обычной печати.

person John1024    schedule 20.09.2014
comment
спасибо за решение, в будущем потребуется некоторое время, чтобы изучить awk. На данный момент я в основном на седе - person josifoski; 20.09.2014

Через Перл,

$ perl -pe 's/^Love.*\K\n//' file
This is some text
Love this or thatHe is running like a rabbit

\K отбрасывает ранее совпавшие символы.

ИЛИ

$ perl -pe '/^Love/ && s/\n//' file
This is some text
Love this or thatHe is running like a rabbit

Если строка начинается со строки Love, то из этой строки удаляется символ новой строки.

person Avinash Raj    schedule 20.09.2014
comment
Используйте chomp, если нужно удалить только новую строку. perl -pe 'chomp if /^Love/' file - person jaypal singh; 20.09.2014

Вот еще одна awkвариация:

awk '{ORS=(/Love/?FS:RS)}1' file
This is some text
Love this or that He is running like a rabbi

Это изменяет ORS на основе шаблона


Вот еще awk

awk '{printf "%s%s",$0,(/Love/?FS:RS)}' file
This is some text
Love this or that He is running like a rabbit

Если в строке есть Love, используйте FS в качестве разделителя, иначе используйте RS

Это тоже должно работать, но используйте первое.

awk '{printf "%s"(/Love/?FS:RS),$0}' file
person Jotne    schedule 20.09.2014
comment
Если вам не нравится пространство между двумя строками, используйте awk '{ORS=(/Love/?"":RS)}1' Даже это можно использовать: awk 'ORS=(/Love/?FS:RS)' - person Jotne; 20.09.2014