简体   繁体   中英

SED: pasting lines between two patterns > sed skips the next pattern match

I have the following scenario

sed -n '/*SET_PART/,/*/p' Inputfile > Outputfile

So I am searching for paragraphs that start with a line containing "*SET_PART" and end with a line that contains "*". (In my scenario the occurence of "*" is always the sign for a new paragraph)

Example: Inputfile

    *SET_PART_COLLECT_TITLE
    Gesamtfahrzeug
           101                                        
       1005043   1005049   1005101   1005102   1005103   1005200   1005300   1005400
       1005504   1005601   1005700   1005800   1005900   1006000   1006100   1006101
       1006102   1006103   1006200   1006201   1006202   1006203   1006400   1006401
       1006402   1006500   1006600   1006700   1006800   1006900   1007000   1007100
       1007200   1007201   1007202   1007203   1007204   1007300   1007301   1007302
       1007303   1007304   1007305   1007306   1007307   1007308   1007309   1007310
       1007311   1007312   1007313   1007314   1007400   1007500   1007600   1007700
       1007800   1007801   1015700   1015800
    *Keyword
           202                                        
       1000000   1002002   1002312   1002313   1002323   1002701
    
    
    *SET_PART_COLLECT_TITLE
    Verbindungstechnik_Slave
           201                                        
       1000000   1002002   1002312   1002313   1002323   1002701
    *SET_PART_LIST_TITLE
    Bord_stein_hi_Forcetransducer
             3        0.        0.        0.        0.
             3
    *SET_PART_COLLECT_TITLE
    *SET_PART_LIST_TITLE
    Fahrbahn_Forcetransducer
             1                                        
             1
    *END

with the current command line I get: Outputfile

    *SET_PART_COLLECT_TITLE
    Gesamtfahrzeug
           101                                        
       1005043   1005049   1005101   1005102   1005103   1005200   1005300   1005400
       1005504   1005601   1005700   1005800   1005900   1006000   1006100   1006101
       1006102   1006103   1006200   1006201   1006202   1006203   1006400   1006401
       1006402   1006500   1006600   1006700   1006800   1006900   1007000   1007100
       1007200   1007201   1007202   1007203   1007204   1007300   1007301   1007302
       1007303   1007304   1007305   1007306   1007307   1007308   1007309   1007310
       1007311   1007312   1007313   1007314   1007400   1007500   1007600   1007700
       1007800   1007801   1015700   1015800
    *Keyword
    *SET_PART_COLLECT_TITLE
    Verbindungstechnik_Slave
           201                                        
       1000000   1002002   1002312   1002313   1002323   1002701
    *SET_PART_LIST_TITLE
    *SET_PART_COLLECT_TITLE
    *SET_PART_LIST_TITLE

The desired Output would be: (all the paragraphs that start with "*SET_PART".)

    *SET_PART_COLLECT_TITLE
    Gesamtfahrzeug
           101                                        
       1005043   1005049   1005101   1005102   1005103   1005200   1005300   1005400
       1005504   1005601   1005700   1005800   1005900   1006000   1006100   1006101
       1006102   1006103   1006200   1006201   1006202   1006203   1006400   1006401
       1006402   1006500   1006600   1006700   1006800   1006900   1007000   1007100
       1007200   1007201   1007202   1007203   1007204   1007300   1007301   1007302
       1007303   1007304   1007305   1007306   1007307   1007308   1007309   1007310
       1007311   1007312   1007313   1007314   1007400   1007500   1007600   1007700
       1007800   1007801   1015700   1015800
    *SET_PART_COLLECT_TITLE
    Verbindungstechnik_Slave
           201                                        
       1000000   1002002   1002312   1002313   1002323   1002701
    *SET_PART_LIST_TITLE
    Bord_stein_hi_Forcetransducer
             3        0.        0.        0.        0.
             3
    *SET_PART_COLLECT_TITLE
    *SET_PART_LIST_TITLE
    Fahrbahn_Forcetransducer
             1                                        
             1

Put in words: I want to match the next occurence of "*" to match, but only print up to the line before it's occurence. And the line in which "*" occured should be the line to search for the next match to "*SET_PART". This is in case there are multiple "*SET_PART" paragraphs in succession.

I use Gnome Version 3.32.2 in case this is relevant.

Is there a better tool than sed for this case?

Thank you for your help

This might work for you (GNU sed):

sed -n '/SET_PART/{:a;p;n;/SET_PART/ba;/*/d;ba}' file

This is essentially a filter operation, so use -n to turn off implicit printing.

Find a line that contains SET_PART and start a loop.

Print the current line and then replace it with the next.

If that line contains SET_PART restart the loop.

If that line contains * , delete it and effectively end the loop.

Otherwise repeat the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM