Description
  • Given a one-line record begins with a timestamp and a hostname, then followed by items which may of the form KEY=value or with KEY only.
  • For example, CE, DF, and SYN consist of no value parts.
  • Two adjacent items are separated by one or more blanks.
  • This script keeps the timestamp, hostname, and IN=, SRC=, PROTO=, SYN while removes the others. Note that there is an unwanted item named PIN=.
  • Each record consists of one line.
Raw Input
Jun 21 21:58:34 adm3 IN=eth0 OUT= MAC=00:60:97:9a:bc:de:ed:cb:a9:ad:9b:60:08:00
SRC=68.59.123.45 DST=67.89.0.123 LEN=48 TOS=00 PREC=0x00 TTL=125 ID=55753 CE DF
PROTO=TCP SPT=1754 DPT=135 SEQ=1875392468 PIN=1 ACK=0 WINDOW=16384 SYN URGP=0
Desired Output
Jun 21 21:58:34 adm3 IN=eth0 SRC=68.59.123.45 PROTO=TCP SYN
Script and Comments
Script1
[ 1] s/^([^ ]+ +){4}/&\n/
[ 2] :loop
[ 3] s/\n((IN|SRC|PROTO)=[^ ]*|SYN)( +|$)/\1\3\n/
[ 4] t loop
[ 5] s/\n[^ ]+( +|$)/\n/
[ 6] t loop
[ 7] s/\n$//
Comments -r
  1. Step [1] inserts a newline character used as an mark before the first item.
  2. Steps [2] thru [6] constitute a loop: In each iteration, the item following the mark is examined:
    • If it is what we want, do nothing on that item, and Step [3] `moves' the mark next to the following item.
    • Otherwise, Step [5] deletes that item and the following blanks, makes the mark next to the following item.
  3. If Step [3] succeeds, command `t' of step [4] will make sed branch to Step [2] (same for Steps [5] and [6]).
  4. Since this script does not append/read the next line via N/n, or delete the current line via d/D, the command sequence s1 t s2 t can be read as: if s1 succeeds, then branches; otherwise, try s2, branches if it succeeds where si stands for a substitution command.