1

I'm not sure what I'm doing wrong. Given a test.log of:

123.123.123.123 321.321.321.321 GET /test1234/asdfasdfpioasdfjkhweris,9
123.123.123.123 321.321.321.321 GET /4321test/asdfasdfpioasdfjkhweris,9
123.123.123.123 321.321.321.321 GET /test123456/asdfasdfpioasdfjkhweris,9

I am trying to isolate the first two by specifying the number of characters between the / and /.

This works

cat test* | awk '{if($4 ~ /^\/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]\//) print $0}'

But this does not

cat test* | awk '{if($4 ~ /^\/[a-zA-Z0-9]{8,}\//) print $0}'

What am I missing?

I've also tried:

cat test* | awk '$4 ~ /^\/[a-zA-Z0-9]{8}\// {print $0}'

which didn't work either.

UPDATE: I also tried the same commands using gawk, which is also available for me to use, and they still didn't work.

7
  • 1
    Is your awk implementation provided by mawk? It looks like mawk doesn't support the {m,n} syntax at all. Try using a more full featured implementation like GNU's gawk. – jw013 May 29 '15 at 3:24
  • @jw013 gawk is also on this machine. Will the same string work with gawk? – user112802 May 29 '15 at 3:27
  • It should, but why don't you just try it and see? – jw013 May 29 '15 at 3:27
  • I did, and it isn't working. I will update my main post. – user112802 May 29 '15 at 3:28
  • 1
    The two awk commands work for me (with GNU awk 4.x). (Older awks may not have supported the brace quantifiers.) - Unrelated, but BTW, you should omit the cat and let awk open the files: awk ' ... ' test*. – Janis May 29 '15 at 4:05
2
cat test* | gawk --re-interval '$4 ~ /^\/[a-zA-Z0-9]{8}\// {print $0}'
# OR
cat test* | gawk --re-interval '{if( $4 ~ "^/[a-zA-Z0-9]{8}/") {print $0}}'

From GNU awk's manpage:

  • --re-interval – Enable the use of interval expressions in regular expression matching

Re also ensuring that at least on numeric digit is included:

gawk --re-interval '$4 ~ "^/[a-zA-Z0-9]{8}/" &&
                    $4 ~ "^/[^/]{0,7}[0-9]" {print $0}'
6
  • Which should of course be equivalent to the non-imperative "awk'ish" form: awk --re-interval '$4 ~ /^\/[a-zA-Z0-9]{8}\//' – Janis May 29 '15 at 4:13
  • @Janis or Peter.O Now how could I ensure there was at least one number in that 8 character string? – user112802 May 29 '15 at 4:18
  • I'd try (untested): awk --re-interval '$4 ~ /^\/[a-zA-Z0-9]{8}\// && substr($4,2,8) ~ /[0-9]/'. – Janis May 29 '15 at 4:22
  • awk --re-interval '$4 ~ /^\/[a-zA-Z0-9]{8}\// && $4 ~ /^\/.{1,7}[0-9]/' test.log appears to work. I'll try your example next. – user112802 May 29 '15 at 4:25
  • Well, that's another option. (Maybe a bit more cryptic than the substr() suggestion.) - But as you wrote it it would not match a leading digit; shouldn't that be {0,7} according to your question? – Janis May 29 '15 at 4:31
0

why not try .. ?

awk -F/ 'length($2) == 8 ' 
  • -F/ use / as separator
  • length($2) compute length
  • default awk action print it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.