Search code examples
awksedcuttr

File output manipulation - ideally in one line


Apologies in advance this is my first post, hope you can understand it etc.

Original File

cat trail
PROC_Create     root     OK          Mon Jun 05 16:05:45 2017 bash                          Global
    forked child process 31522922
PROC_Execute    root     OK          Mon Jun 05 16:05:45 2017 audit                         Global
    euid: 0 egid: 0 epriv: ffffffff:ffffffff name audit shutdown


vi and :set list

PROC_Create     root     OK          Mon Jun 05 16:05:45 2017 bash                          Global                    $
    forked child process 31522922$
PROC_Execute    root     OK          Mon Jun 05 16:05:45 2017 audit                         Global                    $
    euid: 0 egid: 0 epriv: ffffffff:ffffffff name audit shutdown $


cat trail | oc -d
0226220                        G   l   o   b   a   l
0226240                                                               \n
0226260                                    f   o   r   k   e   d       c
0226300    h   i   l   d       p   r   o   c   e   s   s       3   1   5
0226320    2   2   9   2   2  \n   P   R   O   C   _   E   x   e   c   u
0226340    t   e                   r   o   o   t                       O
0226360    K                                           M   o   n       J
0226400    u   n       0   5       1   6   :   0   5   :   4   5       2
0226420    0   1   7       a   u   d   i   t
0226440
0226460                    G   l   o   b   a   l
0226500                                                           \n
0226520                                e   u   i   d   :       0       e
0226540    g   i   d   :       0       e   p   r   i   v   :       f   f
0226560    f   f   f   f   f   f   :   f   f   f   f   f   f   f   f
0226600    n   a   m   e       a   u   d   i   t       s   h   u   t   d
0226620    o   w   n      \n
0226625

Desired Output

Ideally using some tools that I can pipe the trail file through such as sed/tr/awk etc.

PROC_Create     root     OK          Mon Jun 05 16:05:45 2017 bash                            Global        forked child process 31522922
PROC_Execute    root     OK          Mon Jun 05 16:05:45 2017 audit                           Global        euid: 0 egid: 0 epriv: ffffffff:ffffffff name audit shutdown

or

PROC_Create     root     OK          Mon Jun 05 16:05:45 2017 bash        forked child process 31522922
PROC_Execute    root     OK          Mon Jun 05 16:05:45 2017 audit       euid: 0 egid: 0 epriv: ffffffff:ffffffff name audit shutdown

I have manged to just remove the carriage returns and the word Global, but am struggling to just remove the carriage return and /or Global on the lines with Global in. Thanks in advance.

I have used the following:

sed 's/Global//g'
tr -d '\n'

but was hoping to do it all with sed but couldn't get it to work when trying to remove the carriage returns.

Larger sample of file

S_PASSWD_READ   root     OK          Mon Jun 05 16:05:37 2017 su                              Global
    audit object read event detected /etc/security/passwd
S_PASSWD_READ   root     OK          Mon Jun 05 16:05:37 2017 su                              Global
    audit object read event detected /etc/security/passwd
FILE_Write      root     OK          Mon Jun 05 16:05:37 2017 su                              Global
    file descriptor = 5 filename =
FILE_Write      root     OK          Mon Jun 05 16:05:37 2017 su                              Global
    file descriptor = 3 filename =
PROC_Execute    root     OK          Mon Jun 05 16:05:37 2017 ksh                             Global
   euid: 0 egid: 0 epriv: ffffffff:ffffffff name -ksh
PROC_Create     root     OK          Mon Jun 05 16:05:37 2017 ksh                             Global
    forked child process 40763616
PROC_Execute    root     OK          Mon Jun 05 16:05:37 2017 termdef                         Global
    euid: 0 egid: 0 epriv: ffffffff:ffffffff name termdef

Solution

  • NOTE: Assuming all input consists of 2-line pairs where the second line is to be appended to the end of the first line.

    A couple (simplistic) awk examples to get the ball rolling:

    awk '/^[a-zA-Z]/ {printf $0} /^ / {print $0}' trail
    

    -or-

    awk '/^[[:alpha:]]/ {printf $0} /^[[:space:]]/ {print $0}' trail
    

    First search pattern is looking for a line that has a letter (lower- or upper-case) in the first postion; if found, use printf to output the entire line but without a carriage return at the end.

    Second search pattern is looking for a line that as a space in the first position; if found, use print to output the entire line with a carriage return at the end.


    Borrowing RavinderSingh13's getline idea to eliminate second search pattern:

    awk '/^[[:alpha:]]/ {printf $0 ; getline ; print}' trail
    

    For each line that starts with a character use printf to output entire line without a carriage return, read next line, print entire line with a carriage return at the end.