简体   繁体   中英

Merged records based on delimiter - Linux

Need to parse a file and to create a new file based on the following criterias:

this is the sample source data

TTTTT001:866:           $READ #R1         FILE (TEST-ACCOUNTS) LOGICAL               00085100
TTTTT001-867-            USING DESCRIPTOR (COMM-ACCOUNTS)                            00085200
TTTTT001-868-            STARTING FROM COMM-ACCOUNTS = WS-ACCT-KEY                   00085300
TTTTT001-869-            RECORD (TEST-ACCOUNTS) RELEASE(NO).                         00085400
TTTTT001-870-                                                                        00085500
TTTTT001-871-           IF NOT (LAST-RESPONSE-CODE = 0 OR 3)                         00085600
TTTTT001-872-             MOVE 122 TO ERROR-ABEND-CODE                               00085700
TTTTT001-873-             PERFORM ZT-ERROR.                                          00085800
--
TTTTT001:1018:           $READ #R3         FILE (TEST-ACCOUNTS)                       00100300
TTTTT001-1019-                              ISN (R1-ISN)                              00100400
TTTTT001-1020-                           RECORD (TEST-ACCOUNTS)                       00100500
TTTTT001-1021-                          RELEASE (NO) HOLD.                            00100600
TTTTT001-1022-                                                                        00100700
TTTTT001-1023-           IF LAST-RESPONSE-CODE NOT = 0                                00100800
TTTTT001-1024-              OR R3-ISN NOT = R1-ISN                                    00100900
TTTTT001-1025-             MOVE 122 TO ERROR-ABEND-CODE                               00101000
--

Looking to get the following

  1. each section is identified by -- (results from the grep)
  2. remove the numbers appears at the end of each line
  3. remove the lines after the . until the --
  4. merge the text starting from $READ until the . into a single line

So the output should be like this

TTTTT001:866:           $READ #R1         FILE (TEST-ACCOUNTS) LOGICAL USING DESCRIPTOR (COMM-ACCOUNTS) STARTING FROM COMM-ACCOUNTS = WS-ACCT-KEY RECORD (TEST-ACCOUNTS) RELEASE(NO).
--
TTTTT001:1018:           $READ #R3         FILE (TEST-ACCOUNTS) ISN (R1-ISN) RECORD (TEST-ACCOUNTS) RELEASE (NO) HOLD.                    
--

您可以尝试使用此sed命令并获得准确的结果。

sed -nr '/[T]+[0-9]+:/{:a;N;/\n--/{p;d;t};/\n.*\./{s/(.*) .*\n[^ ]+-(.*) .*/\1 \2/g;s/ +/ /g;p;d;t};s/(.*) .*\n[^ ]+-(.*) .*/\1 \2/g;s/ +/ /g; t a;}' FileName

Save the following code as sed.in and then sed -nr -f sed.in filename . It works with you sample input on my Ubuntu14.04 with GNU sed version 4.2.2.

I have add comment to this script in case you want to understand and modified it according to your own need. Check this if you want to learn how to use sed.

s/[ \t]*[0-9]*$//;h         # remove trailing number and space, then save it to hold space
:back                       # label
n                           # next line
s/[ \t]*[0-9]*$//           # remove trailing number and space
s/TTTTT[^ ]*[ \t]+(.*$)/\1/ # remove heading and spaces
/\.$/ !{                    # if it's not the line end with '.', append it to hold space
    H
    bback                   # jump to label back
}
/\.$/ {                     # line end with '.'
    H                       # append
    :aa                     # label
    n                       # get next line
    /^--/ !baa              # if it's not line start with '--' skip it
    /^--/ {
        x                   # swap hold space and pattern space
        s/\n/ /g;p          # substitute \n with space and print it
        s/^.*$//            # empty pattern space
        x                   # swap space
        b                   # get into next cycle
    }
}

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