ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
I'm trying to substitute "Owner and Operator" with "Installation" and to bring "Guide" on the same line, so as to read "Installation Guide", and then start a newline (the last thing is easy). But to do that I want to match "Owner and Operator*newline*newline*space*. Even more, I would like it to match any combination of newline and spaces (perhaps including tabs), regardless of the order. For example, newline-space-newline or doublespace-newline-tab-newline and so on, and so forth.
If I remember correctly, you could do it with square brackets, but I'm not sure how I can do that using \n, \s or \t or regex classes.
This is the original idea:
Code:
/Owner/{
N
s/Owner *\n*and *\n*Operator *\n*Guide/Installation Guide\
/
}
which matches "Owner Operator Guide", even if it's broken across multiple lines, but it doesn't take into account tabs or spaces that occur after the newline,or tabs before the line or some other random order.
I guess one of the first problems I need to solve is to somehow 'catch' the second newline. The first newline is caught with N (if I understand correctly). So how can I match several newlines?
I've moved this thread to the Programming forum. I know that persons regularly on the Programming forum will have some thoughts. Myself, I've not played much with newline and regex, instead I've always tackled that internally within an editor a'la copy or cut and then paste that into the search-replace buffer.
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
This is another paragraph.
This is yet another paragraph.
Consult Section 3.1 in the Installation Guide
for a description of the tape drives
available on your system.
This is another paragraph.
This is yet another paragraph.
Explanation: tr replaces all newlines with tilde. sed implements the desired transformation. tr replaces all tildes with newlines.
I find it a little bit hard to digest it, but at the same time the logic seems simple enough. So you're using tildes just for transition. That's interesting. Thanks. I did expect it to solve it only with sed, just to get to know the tool better, but I guess it's unecessarily intricate.
I find it a little bit hard to digest it, but at the same time the logic seems simple enough. So you're using tildes just for transition. That's interesting. Thanks. I did expect it to solve it only with sed, just to get to know the tool better, but I guess it's unnecessarily intricate.
The first tr changes the entire file into one long line, with tildes as "ghosts" of former newlines. The sed becomes less complicated because it isn't trying to "peek" one or two lines ahead. After sed does its work, another tr replaces any remaining "ghosts" with newlines.
$ sed -r '/Owner/,/Guide/{:a;N;$!ba;s/[ \t\n]+/ /g;s/Owner and Operator/Installation/;s/Guide /Guide\n/}' file.txt
Consult Section 3.1 in the Installation Guide
for a description of the tape drives available on your system.
I have put it on a single line, but you might want to break it up for readability.
UPDATE: End address had no effect because of inner loop as pointed out by danielbmartin - but I had not noticed because with simpler infile it did not matter in quick testing. Moving end address to inner loop test (where it should have been) fixes it for longer infiles, see below.
Last edited by astrogeek; 03-07-2017 at 11:44 PM.
Reason: Improved /Guide../
$ sed -r '/Owner/,/Guide/{:a;N;$!ba;s/[ \t\n]+/ /g;s/Owner and Operator/Installation/;s/Guide /Guide\n/}' file.txt
Using the InFile shown in post #4 this sed produced this OutFile ...
Code:
Consult Section 3.1 in the Installation Guide
for a description of the tape drives available on your system. This is another paragraph. This is yet another paragraph.
It blew away the newlines which separate paragraphs.
AH! So it did! I was working only with the original file snippet.
Try this then...
Code:
$ sed -r '/Owner/{:a;N;/Guide/!ba;s/[ \t\n]+/ /g;s/Owner and Operator/Installation/;s/Guide */Guide\n/}' file.txt
Consult Section 3.1 in the Installation Guide
for a description of the tape drives
available on your system.
This is another paragraph.
This is yet another paragraph.
I see a few other changes that could be made, but I think this meets the originally stated conditions. The main point being, of course, to remove multi-line whitespace between the start and end condition and make the given replacements, adjust to suite actual requirements!
Last edited by astrogeek; 03-07-2017 at 06:40 PM.
Reason: Simpler and added comment... meh typos...
/Owner and Operator/{
# substitute what has matched
s//Installation/
:L
# append the following line with a \n
N
# delete it if blank
s/\n *$//
# repeat if successful
tL
# join the following line
s/\n//
}
Last edited by MadeInGermany; 03-09-2017 at 01:30 PM.
Consult Section 3.1 in the Owner and Operator
Guide for a description of the tape drives
available on your system.
This is another paragraph.
This is yet another paragraph.
Consult Section 3.2 in the Owner and Operator
Guide for a description of the disk drives
available on your system.
This is another paragraph.
This is yet another paragraph.
... the perl solution treats only the first Owner and Operator text string. Previous solutions in this thread handle all instances. Is there an easy fix?
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.