LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   sed print range from pattern1 to pattern2 (https://www.linuxquestions.org/questions/programming-9/sed-print-range-from-pattern1-to-pattern2-886347/)

porphyry5 06-14-2011 03:38 PM

sed print range from pattern1 to pattern2
 
From a file I want to extract a range of lines by patterns. I've used variations on
Code:

sed -n -e '/^BashNotes/,/^EndOf[A-Za-z]*$/ p' -e '/^EndOf[A-Za-z]*$/ q' Notes
So, I want to extract lines starting from one whose first word is specified, in this case "BashNotes", and ending at the first line consisting of the single word "EndOf...", which in this case would be "EndOfBashNotes".

Either I get no output at all, or it prints from the start of file to the first EndOf..., so the problem has to be with "^BashNotes", e.g. remove the "^" and it accesses an earlier occurrence of "BashNotes" that is in the middle of the first line of the file, and prints to the first occurrence of "EndOf...".

So why should a "^" in the "from" pattern be objectionable, when it is acceptable in the "to" pattern and the "quit" statement?

crts 06-14-2011 07:31 PM

Quote:

Originally Posted by porphyry5 (Post 4385695)
From a file I want to extract a range of lines by patterns. I've used variations on
Code:

sed -n -e '/^BashNotes/,/^EndOf[A-Za-z]*$/ p' -e '/^EndOf[A-Za-z]*$/ q' Notes
So, I want to extract lines starting from one whose first word is specified, in this case "BashNotes", and ending at the first line consisting of the single word "EndOf...", which in this case would be "EndOfBashNotes".

Either I get no output at all, or it prints from the start of file to the first EndOf..., so the problem has to be with "^BashNotes", e.g. remove the "^" and it accesses an earlier occurrence of "BashNotes" that is in the middle of the first line of the file, and prints to the first occurrence of "EndOf...".

So why should a "^" in the "from" pattern be objectionable, when it is acceptable in the "to" pattern and the "quit" statement?

Hi,

without some sample data it is hard to guess why it does not work. Maybe some leading spaces? Try
Code:

sed -n -e '/^[[:blank:]]*BashNotes/ ...'
If this does not fix the issue then provide a representative sample file.

porphyry5 06-14-2011 09:35 PM

1 Attachment(s)
Quote:

Originally Posted by crts (Post 4385842)
Hi,

without some sample data it is hard to guess why it does not work. Maybe some leading spaces? Try
Code:

sed -n -e '/^[[:blank:]]*BashNotes/ ...'
If this does not fix the issue then provide a representative sample file.

Has the same result, nothing is returned. There is no leading whitespace. I apologize, I should have mentioned in the first post that my regexes work exactly as expected in a different text editor, kwrite as it happens, but I was thinking I had to have made some syntactical error with sed. I've attached the front end of the file concerned.

crts 06-14-2011 10:38 PM

Ok, I see now. Try the following to see the error:
Code:

$ sed -n -e '/^EndOf[A-Za-z]*$/ p' -e '/^EndOf[A-Za-z]*$/ q' Notes
EndOfAwkCommands

As you can see, your RegEx matches 'EnOfAwkCommands' and therefore it quits. Since there 'BashNotes' has not been encountered before - when you use the 'sed' in your initial post - nothing will get printed.
This worked for me:
Code:

sed -n '/^BashNotes/,/^EndOf[A-Za-z]*$/ p' Notes
It printed 624 lines. I am not sure why you want to use the 'q' command.

Reuti 06-15-2011 04:47 AM

Depending on the size maybe the q command can save some time (and/or avoid to find any further block of BashNotes/EndOf...).

porphyry5 06-15-2011 08:48 AM

Quote:

Originally Posted by crts (Post 4385963)
Ok, I see now. Try the following to see the error:
Code:

$ sed -n -e '/^EndOf[A-Za-z]*$/ p' -e '/^EndOf[A-Za-z]*$/ q' Notes
EndOfAwkCommands

As you can see, your RegEx matches 'EnOfAwkCommands' and therefore it quits. Since there 'BashNotes' has not been encountered before - when you use the 'sed' in your initial post - nothing will get printed.
This worked for me:
Code:

sed -n '/^BashNotes/,/^EndOf[A-Za-z]*$/ p' Notes
It printed 624 lines. I am not sure why you want to use the 'q' command.

Thank you very much. You mean that the quit statement gets a match before it ever gets to BashNotes. I was under the impression that the commands proceeded stepwise, that the range match would have to complete before it ever tried the quit test. That was only there to stop it processing any further once it satisfied the range command.

crts 06-15-2011 09:06 AM

Quote:

Originally Posted by porphyry5 (Post 4386417)
You mean that the quit statement gets a match before it ever gets to BashNotes.

Yes, that is exactly what happens. If for some reason you want to quit processing after the range has been printed then you can do the following:
Code:

sed -n '/^BashNotes/,/^EndOf[A-Za-z]*/ {p;/^EndOf[A-Za-z]*/q}' Notes
This will execute the 'q' command only when inside the range. Notice, that I removed the 'end of line' marker '$' to accommodate for trailing spaces.

porphyry5 06-15-2011 09:57 AM

Quote:

Originally Posted by crts (Post 4386441)
Yes, that is exactly what happens. If for some reason you want to quit processing after the range has been printed then you can do the following:
Code:

sed -n '/^BashNotes/,/^EndOf[A-Za-z]*/ {p;/^EndOf[A-Za-z]*/q}' Notes
This will execute the 'q' command only when inside the range. Notice, that I removed the 'end of line' marker '$' to accommodate for trailing spaces.

Thank you again, so one uses {...} to ensure the previous command is satisfied before accessing the commands in the braces. No harm is done by removing either ^ or $, I only use those compound word arrangements for titles and end markers, to distinguish them from regular text, so any range combination can only occur once.


All times are GMT -5. The time now is 02:38 AM.