0

I have a text that looks like the following.

<div><p class="title">software
v1.0.1.0
download</p></div>
<div><p class="title">software
v1.0.2.0
download</p></div>
<div><p class="title">software
v1.0.3.0
download</p></div>

I need to replace the newline character in the <p class="title">...</p> range. Make it look like the following.

<div><p class="title">software v1.0.1.0 download</p></div>
<div><p class="title">software v1.0.2.0 download</p></div>
<div><p class="title">software v1.0.3.0 download</p></div>

Can I use sed to do this? Any help is appreciated in advance!

4
  • Are the newlines (or the lack of them) actually relevant for the rendering of the text in a browser?
    – Kusalananda
    Commented Sep 27, 2020 at 7:35
  • @Kusalananda no, it has nothing to do with the line feed the browser displays.
    – Matthew
    Commented Sep 27, 2020 at 8:02
  • @Matthew. You need to modify your question. My answer, and others, matches your sample input and output yet you say it is incorrect. You obviously are not providing sufficient information.
    – fpmurphy
    Commented Sep 27, 2020 at 8:22
  • 1
    When your file has a special kind of regularity (here, starting from the 1st line, every three lines contains the block to be joined in one line), it is useful to explicitly state that, so answers don't have to assume that is a guaranteed pattern in the whole file instead of just a coincidence.
    – Quasímodo
    Commented Sep 27, 2020 at 12:09

5 Answers 5

2

If your file only consists of these 3 "repeating" lines, you could use the following:

$ sed 'N;N;s/\n/ /g' file

This produces:

<div><p class="title">software v1.0.1.0 download</p></div>
<div><p class="title">software v1.0.2.0 download</p></div>
<div><p class="title">software v1.0.3.0 download</p></div>

Use the following sed script if your file contains other lines:

$ sed '/class="title"/ { N;N;s/\n/ /g }' file
4
  • It has a problem. If <p class="title">...</p> is also followed by a newline character, it will also be replaced.
    – Matthew
    Commented Sep 27, 2020 at 6:57
  • @Matthew. You need to modify your question. My answer, and others, matches your sample input and output yet you say it is incorrect. You obviously are not providing sufficient information.
    – fpmurphy
    Commented Sep 27, 2020 at 8:21
  • Sorry, this is my negligence. Just tested it and it works fine.
    – Matthew
    Commented Sep 27, 2020 at 8:38
  • I imagine using y/// in place of s///g would be faster since it's a simple translation of newlines into spaces.
    – Kusalananda
    Commented Sep 27, 2020 at 11:33
2

For GNU you can use following sed

sed -n '/class="title"/{N;s/\n/ /;N;s/\n/ /p;}' file.txt

N appends next line to the pattern space

4
  • It doesn't seem to end the boundary, which leads to replacing out-of-scope line feeds.
    – Matthew
    Commented Sep 27, 2020 at 3:33
  • @Matthew what do you mean out of scope? this will matches only for lines contain class="title" then it adds next line and remove newline and repeat. and finally it will print only the matched lines.
    – binarysta
    Commented Sep 27, 2020 at 7:37
  • If <p class="title">...</p> is also followed by a newline character, it will also be replaced. Can the replacement operation be limited to <p class="title">...</p>?
    – Matthew
    Commented Sep 27, 2020 at 7:46
  • Sorry, this is my negligence. Just tested it and it works fine.
    – Matthew
    Commented Sep 27, 2020 at 8:39
2

You don't even need sed here. You could do it with paste:

paste -d ' ' - - - < file

Or:

paste -sd '  \n' file

To replace newlines with space between <p class="title"> and the next occurrence of </p> after that:

perl -0777 -pe 's{<p class="title">.*?</p>}{$& =~ y/\n/ /r}gse' < file
2
  • Can limit the replacement operation to the <p class="title">...</p> range? Because the actual file isn't as simple as the example, there are many other lines.
    – Matthew
    Commented Sep 27, 2020 at 7:55
  • @Matthew, see edit. Commented Sep 27, 2020 at 12:03
1
Done by below 2 methods awk and Python


sed command

sed -e "N;s/\n/ /g" -e "N;s/\n/ /g" filename




Python

#!/usr/bin/python
f=[]
k=open('filename','r')
for  i in k:
    f.append(i.strip())

for n in range(0,len(f),3):
    print f[n:n+3]

output

<div><p class="title">software v1.0.1.0 download</p></div>
<div><p class="title">software v1.0.2.0 download</p></div>
<div><p class="title">software v1.0.3.0 download</p></div>
1

Your question can be interpreted as how to fold lines, and print the newline only when a <div> is closed. Of course this applies for your simple html bit and not for any html. Here is using awk:

awk '{ORS = (/\/div>$/? "\n": " ")} 1' file

Set the ORS (output record separator) to newline, if /div> matched at the end of a line, or else set ORS to space. 1 means {print} every line.

<div><p class="title">software v1.0.1.0 download</p></div>
<div><p class="title">software v1.0.2.0 download</p></div>
<div><p class="title">software v1.0.3.0 download</p></div>

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .