1

I would like to extract contents between Station Name and Data End of the file:

Structure of text file for clarification:

---- Huge text -- not interested
Station Name 
100 - 200 lines
Data End
---- Again text --- 

How would I easily extract the data?

To ask in general, how can we find the data in particular section and then process over it (delete/replace ... etc) i.e. before a specific word? or after a specific word? or between them?

Desired Output

Case 1: From beginning to given word/pattern
Case 2: Between 2 given words/pattern
Case 3: From the given word/pattern to end of file.

2
  • It is not a duplicate of that other question since here we don't want to exclude the boundaries Commented Oct 18, 2012 at 19:30
  • 2
    Can you edit the question and add a desired output? It looks still like a duplicate to me
    – daisy
    Commented Oct 19, 2012 at 1:22

2 Answers 2

4
sed '/Station Name/,$!d; /Data End/q'

That is delete any line except for the first one containing "Station Name" and up to the last line ($). Then for those that lines that have escaped the d command, quit if it matches "Data End" (but print it before quitting).

So it prints the lines between the first occurrence of "Station Name" and the first occurrence of "Data End" after that (including if on the same line as "Data End").

Now, if the boundaries are to be ommitted, it's more complicated.

sed -ne '1,/Station Name/d; /Data End/!{p;n;}' -e q

Would work except if "Station Name" is to be found on the first line or on the same line as "Data End". Some sed implementation allow you to refer to line 0 in a line range, but that's not portable. There are work arounds though. See the sed FAQ.

It gets even more complicated if you want to find the text between the first occurence of "Station Name" and the last occurrence of "Data End" because in that case, you're never sure you've reached the last "Data End" before you've reached the end of the file. sed would need to hold the lines it's seen after seeing a "Data End" until the end of the file or the next occurrence of "Data End", and because POSIX doesn't require sed implementations to be able to hold more than 10 lines of input, it can't be done portably with sed so you'd need to use other tools like perl or awk or do several passes into the file.

0

Using Raku (formerly known as Perl_6)

Output all lines of a file from start up to (and not including) a "sentinel" line:

~$ raku -e 'my Str $K1 = "Station Name"; put slurp.split($K1)[0];'   file
---- Huge text -- not interested

#OR:

~$ raku -ne 'BEGIN my @a; @a.push: $_ unless /Station \s Name/ && last; END .put for @a;'   file
---- Huge text -- not interested 

#OR:

~$ raku -ne '.put unless /Station \s Name/ fff *;'   file
---- Huge text -- not interested

Output lines between (and including) two "sentinel" lines (caution--will filter-in multiple records satisfying this "Start-Line/Stop-Line" pattern):

~$ raku -ne '.put if  /Station \s Name/ fff /Data \s End/;'  file  
Station Name 
100 - 200 lines
Data End

Output all lines of a file from (and not including) a "sentinel" line to end of file:

~$ raku -e 'my Str $K2 = "Data End\n"; put slurp.split($K2, 2)[1];'   file 
---- Again text --- 

#OR:

~$ raku -ne '.put if /Data \s End/ ^fff *;'   file
---- Again text --- 

Note: Raku's / … / fff / … / "flip-flop" operator has multiple options, with the additional ^fff, fff^ and ^fff^ variant operators. The ^ caret indicates that the recognized line doesn't show up in the return value (unless the statement is negated).

Sample Input:

---- Huge text -- not interested
Station Name 
100 - 200 lines
Data End
---- Again text --- 

https://docs.raku.org/language/operators#infix_fff
https://raku.org

You must log in to answer this question.

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