echo xx y11y rrr | awk '{ if ($2 ~/y[1-5]{2}y/) print $3}'
Why I cannot get any output?
Thank you.
You need to enable "interval expressions" in regular expression matching by specifying either the --posix or --re-interval option.
e.g.
echo xx y11y rrr | awk --re-interval '{ if ($2 ~ /y[1-5]{2}y/) print $3}
From the man page:
--re-interval
Enable the use of interval expressions in regular expression matching (see Regular Expressions, below). Interval expressions were
not traditionally available in
the AWK language. The POSIX standard added them, to make awk and egrep consistent with each other. However, their use is
likely to break old AWK programs, so
gawk only provides them if they are requested with this option, or when --posix is specified.
You should force POSIX to use {} in awk
echo xx y11y rrr | awk -W posix '{ if ($2 ~/y[1-5]{2}y/) print $3}'
On my machine:
$ echo xx y11y rrr | awk '{ if ($2 ~/y[1-5]{2}y/) print $3}'
rrr
Was this what you wanted? I'm using GNU awk 4.0.0 in Cygwin on Windows XP.
Related
Here is the file contents:
# cat text
16:10:29 DEBUG MY_Output:90 1 5de0d275c2f55: send response
As I do regex map with awk:
# cat text | awk '{if($0~/[0-9]{2}:[0-9]{2}:[0-9]{2}.*/) print $0}'
(print nothing)
# cat text | awk '/[0-9]{2}:[0-9]{2}:[0-9]{2}.*/ {print $0}'
(print nothing)
# cat text | awk '/[0-9]{2}:[0-9]{2}:[0-9]{2}.*/1'
16:10:29 DEBUG MY_Output:90 1 5de0d275c2f55: send response
My Question is:
why {if($0~/[0-9]{2}:[0-9]{2}:[0-9]{2}.*/) print $0} , /[0-9]{2}:[0-9]{2}:[0-9]{2}.*/ {print $0} print nothing, but /[0-9]{2}:[0-9]{2}:[0-9]{2}.*/1 print the result.
As I expected, the three expressions play the same meaning, as [1] describes, 1, {print}, {print $0} do the same thing in action.
Also the another experiment likely to check:
# awk '{if(/[0-9]{2}:[0-9]{2}:[0-9]{2}/) print $0}' <<< "16:10:29"
(print nothing)
# awk '/[0-9]{2}:[0-9]{2}:[0-9]{2}/{print $0}' <<< "16:10:29"
(print nothing)
# awk '/[0-9]{2}:[0-9]{2}:[0-9]{2}/1' <<< "16:10:29"
16:10:29
Thank you very much.
After knowing OP's awk version(in comments section) looks like it it OLD one so [0-9]{2} is NOT supported in it(I believe so), so can you try following command once.
awk '/[0-9][0-9]:[0-9][0-9]:[0-9][0-9]/' Input_file
This should work with your provided awk version.
Also with old version of awk you could use --re-interval to get it worked, I don't have that version with me so couldn't test it.
awk --re-interval '/[0-9]{2}:[0-9]{2}:[0-9]{2}/' Input_file
In older versions of awk to invoke EREs we need to include --re-interval with awk codes, hence it is NOT working with normal awk code.
NOTE: In new versions of gawks --re-interval is depreciated since OP has old version of awk so have mentioned it in solution. Adding cross site reference link https://unix.stackexchange.com/questions/354553/awk-repetition-n-is-not-working as per OP's comments too here.
echo xx y11y rrr | awk '{ if ($2 ~/y[1-5]{2}y/) print $3}'
Why I cannot get any output?
Thank you.
You need to enable "interval expressions" in regular expression matching by specifying either the --posix or --re-interval option.
e.g.
echo xx y11y rrr | awk --re-interval '{ if ($2 ~ /y[1-5]{2}y/) print $3}
From the man page:
--re-interval
Enable the use of interval expressions in regular expression matching (see Regular Expressions, below). Interval expressions were
not traditionally available in
the AWK language. The POSIX standard added them, to make awk and egrep consistent with each other. However, their use is
likely to break old AWK programs, so
gawk only provides them if they are requested with this option, or when --posix is specified.
You should force POSIX to use {} in awk
echo xx y11y rrr | awk -W posix '{ if ($2 ~/y[1-5]{2}y/) print $3}'
On my machine:
$ echo xx y11y rrr | awk '{ if ($2 ~/y[1-5]{2}y/) print $3}'
rrr
Was this what you wanted? I'm using GNU awk 4.0.0 in Cygwin on Windows XP.
In awk I can search a field for a value like:
$ echo -e "aa,bb,cc\ndd,eaae,ff" | awk 'BEGIN{FS=",";}; $2=="eaae" {print $0};'
aa,bb,cc
dd,eaae,ff
And I can search by regular expressions like
$ echo -e "aa,bb,cc\ndd,eaae,ff" | awk 'BEGIN{FS=",";}; /[a]{2}/ {print $0};'
aa,bb,cc
dd,eaae,ff
Can I force the awk to apply the regexp search to a specific field ? I'm looking for something like
$ echo -e "aa,bb,cc\ndd,eaae,ff" | awk 'BEGIN{FS=",";}; $2==/[a]{2}/ {print $0};'
expecting result:
dd,eaae,ff
Anyone know how to do it using awk?
Accepted response - Operator "~" (thanks to hek2mgl):
$ echo -e "aa,bb,cc\ndd,eaae,ff" | awk 'BEGIN{FS=",";}; $2 ~ /[a]{2}/ {print $0};'
You can use :
$2 ~ /REGEX/ {ACTION}
If the regex should apply to the second field (for example) only.
In your case this would lead to:
awk -F, '$2 ~ /^[a]{2}$/' <<< "aa,bb,cc\ndd,eaae,ff"
You may wonder why I've just used the regex in the awk program and no print. This is because your action is print $0 - printing the current line - which is the default action in awk.
I can't get the following to match any IP addresses
awk '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/{print $0}' maillog
or this one...
awk '/[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}/' maillog
but this works...
awk '/127.0.0.1/{print $0}' maillog
and so does this...
awk '/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]/{print $0}' maillog
What am I doing wrong in the first two?
To use interval {1,3} with gnu awk you my need to enable it with --re-interval like this:
awk --re-interval '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/{print $0}' maillog
They are just fine.
The following is working for me.
$ echo "2.168.1.1" | awk '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/{print $0}'
2.168.1.1
$ echo "2.1.1.1" | awk '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/{print $0}'
2.1.1.1
$ echo "22.1.1.1" | awk '/[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/{print $0}'
22.1.1.1
I would investigate your maillog and make sure that everything there is in plaintext.
I need to filter with sed only the ports from /usr/share/nmap/nmap-services
tcpmux 1/tcp 0.001995 # TCP Port Service Multiplexer [rfc-1078]
compressnet 2/tcp 0.000013 # Management Utility
compressnet 3/tcp 0.001242 # Compression Process
unknown 4/tcp 0.000477
unknown 6/tcp 0.000502
echo 7/tcp 0.004855
unknown 8/tcp 0.000013
discard 9/tcp 0.003764 # sink null
unknown 10/tcp 0.000063
systat 11/tcp 0.000075 # Active Users
I've tryed something like (!?([0-9]+/tcp))
But it wont work: why?
Thank you
Try doing this :
grep -oP '\d+(?=/(udp|tcp))' /usr/share/nmap/nmap-services
or with perl :
perl -lne 'print $& if m!\d+(?=/(udp|tcp))!' /usr/share/nmap/nmap-services
I use a positive look ahead advanced regex, see http://www.perlmonks.org/?node_id=518444
or with awk without advanced regex :
awk '{gsub("/.*", ""); print $2}' /usr/share/nmap/nmap-services
or
awk -F'[ /\t]' '{print $2}' /usr/share/nmap/nmap-services
Here's an example using AWK
cat /usr/share/nmap/nmap-services | awk '{print $2}' | awk -F\/ '{print $1}'
The simplest is so:
cut -s -d\ -f2 test
You can also do it so:
sed '/[^ ]* \([^ ]*\).*/ s::\1:; /^$/d' FILE
cut variant prints empty lines for non-matching.