2

Can anybody help in resolving this issue? Not sure wht it is giving problem.

ssh root@host1 "tail -f /data1/logs/logger.log | awk '{ if(\$0 ~ /^Mar|^Apr/) { printf(\"\\n%s\",\$0) } if(\$0 \!~ /^Mar|^Apr/) { printf(\"%s\", \$0);} };' " root@host1's password: awk: { if($0 ~ /^Mar|^Apr/) { printf("\n%s",$0) } if($0 \!~ /^Mar|^Apr/) { printf("%s", $0);} }; awk: ^ backslash not last character on line 
3
  • 1
    Don't put a backslash there? If you are grappling with Bash's Csh-style history expansion, try set -H to disable it. Commented Apr 1, 2014 at 10:29
  • @tripleee removing the backslash doesn't work - even with set -H I still get bash: !~: event not found. One solution is to use single quotes round the whole thing (as shown in my answer). Commented Apr 1, 2014 at 11:44
  • 1
    Sorry, I guess that should have been set +H. Commented Apr 1, 2014 at 15:22

2 Answers 2

1

Rather than testing over ssh, you can replicate the behaviour using eval. I made a test file (called month):

Mar line1 line2 line2 Apr line3 

You have (at least) three options:

First option

Your two options are mutually exclusive, so you can sidestep the issue of escaping a ! entirely by using two blocks with next in the first block:

eval "awk '/^Mar|^Apr/ { printf(\"\\n%s\",\$0); next } { printf(\"%s\", \$0) }' month" 

If the condition is true, the first block is taken and next skips the rest. Note that I have removed the unnecessary $0 ~ from the condition. The match is performed against the whole line by default.

Second option

You could actually just do this:

eval "awk '/^Mar|^Apr/ { \$0 = \"\\n\"\$0 } { printf(\"%s\", \$0) }' month" 
  1. If the line matches, precede it with a newline.
  2. In all cases (no condition before the { }), print the line.

Third option

If you wrap the overall command in single quotes, you don't need to do anything fancy with the !:

eval 'awk "{ if(/^Mar|^Apr/) { printf(\"\\n%s\",\$0) } if(!/^Mar|^Apr/) { printf(\"%s\", \$0)} }" month' 

I recommend one of the other two solutions, I just thought that it would be worth showing that you can use ! within the command if you need to.

Output for all three cases:

Mar line1line2 line2 Apr line3 
Sign up to request clarification or add additional context in comments.

Comments

0

Here is a cleaned up version of your awk

awk '/^Mar|^Apr/ {printf "\n%s",$0;next} {printf "%s",$0}' 

This will test if $0 (default, so need to add) is starting with Mar or Apr
If yes do printf "\n%s",$0;next.
The next makes final code to be rune only if $0 is not starting with Mar or Apr
Then run printf "%s",$0

Or just:

awk '/^Mar|^Apr/ {$0="\n"$0} {printf "%s",$0}' 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.