1

Input.txt

-------
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

Expected Output

-------
Database alias  = ABC
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

Idea is to remove the Duplicate Values of Hostname & Service Name if repetative or you can say Remove lines between '-------', if there are 2 lines in between.

Tried using sed with Multiple Match, but not getting desired o/p

sed '/-------/{$!N;/\n.*Hostname/d;}' Input.txt
3
  • 2
    Well, you're really close there... You need to pull in two lines when you encounter a match and then delete, otherwise just do nothing. It's easier if you negate the condition (assuming gnu sed here, based on your code): sed '/-------/{$!N;/\nHostname/!b;N;d;}' infile Mar 27, 2018 at 18:26
  • 1
    @don_crissti is right (as usual), except I'd suggest to make it work on POSIX sed as well: sed -e '/-------/{$!N;/\nHostname/!b' -e '$!N;d;}'
    – Philippos
    Mar 27, 2018 at 18:28
  • I presumed that the duplicate entries might not be consecutive ... Mar 27, 2018 at 18:29

3 Answers 3

0

This isn't a job for sed (you shouldn't depend upon the duplicate entries being consecutive). Use awk:

  1. Set the record separator to the regex ^-+$.

  2. Use an associative array, where the index is a concatenation of HostName and ServiceName. For any record read, place the record in the array only if it does not already exist.

  3. At the end of processing the file, print out all elements of the array, formatted into separate lines, with your ---- delimiter lines.

0

GNU awk approach:

awk 'BEGIN{ 
         RS = ORS = "-------\n";
         pat = "^Hostname += ([^ ]+)\nService name += ([^ ]+)\n$";  
     }
     NR == FNR{ 
         if (match($0, pat, a)) { items[a[1], a[2]]++ } 
         next 
     }
     match($0, pat, a) && (a[1], a[2]) in items \
     && items[a[1], a[2]] > 1{ next }1' inout.txt input.txt

The output:

-------
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......
-------
0

Perhaps the simplicity of your sample dataset is not typical of the actual use case, but given the triviality of the example you post, grep alone would suffice:

$ grep --no-group-separator -A4 '^Database alias' input.txt 
Database alias = ABC
Node name = node01
Hostname = hostnode01
Service name = 12345
-------
Database alias  = PQR
Node name   = node01
Hostname    = hostnode01
Service name    = 12345
-------
Database alias  = XYZ ......

You must log in to answer this question.

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