Jim
Jim

Reputation: 161

sed statement syntax wrong?

My sed only works if the input file last entry is 'in', how would I get it to work if file has 'in' or 'out'? I've tried different variations with no success.

egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/'
egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/ out/ out/'
egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/ || out/ out/'

input file

Apr 6 08:54:23 TCP 212.58.244.58:80 in

Apr 6 09:29:09 TCP 212.58.244.58:443 out

Upvotes: 0

Views: 184

Answers (3)

potong
potong

Reputation: 58391

This might work for you:

sed '/\<\(TCP\|UDP\)\>/!d;s/:[^:]*\(in\|out\)/ \1/' denied.txt
Apr 6 08:54:23 TCP 212.58.244.58 in
Apr 6 09:29:09 TCP 212.58.244.58 out

Or more simply:

sed '/\<\(TCP\|UDP\)\>/!d;s/:[^ ]*//2' denied.txt
Apr 6 08:54:23 TCP 212.58.244.58 in
Apr 6 09:29:09 TCP 212.58.244.58 out

Upvotes: 1

Jonathan Leffler
Jonathan Leffler

Reputation: 753695

You have3 examples:

  1. egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/'

    This should work on lines ending in.

  2. egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/ out/ out/'

    This will fail with syntax errors from sed. The first part is a valid s/// command, up to the slash after the second in; the rest should be a new command, such as:

    egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/; s/:[^:]* out/ out/'
    

    That should work on in and out with any version of sed.

  3. egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* in/ in/ || out/ out/'

    As with the previous diagnosis, the material after the first s/// is simply not valid sed.

Standard sed uses a moderately power version of regular expressions, but it is not the full ERE (extended regular expression). In particular, it does not support alternation (or'd alternatives).

Some modern versions of sed (notably GNU sed) support ERE and even PCRE (Perl-compatible Regular Expressions).

egrep -w 'TCP|UDP' denied.txt | sed -r 's/:[^:]* (in|out)/ \1/'

Failing that, to process 'in' and 'out' with a single substitute, you could use:

egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* \([io][nu]t\{0,1\}\)/ \1/'

Granted, that will map on and iut and int and so on as well as in and out; the question for you would be 'could such oddities occur in your data'? If so, then the two explicit s/// commands is better.

Finally, all the regular expressions might benefit from a $ after the in or out to ensure the substitution only occurs at the end of the line.

Upvotes: 1

Mat
Mat

Reputation: 206689

Try with:

egrep -w 'TCP|UDP' denied.txt | sed 's/:[^:]* \(in\|out\)/ \1/'

See sed regular expressions.

Upvotes: 2

Related Questions