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, 2015 at 3:24
  • @jw013 gawk is also on this machine. Will the same string work with gawk?
    – user112802
    May 29, 2015 at 3:27
  • It should, but why don't you just try it and see?
    – jw013
    May 29, 2015 at 3:27
  • I did, and it isn't working. I will update my main post.
    – user112802
    May 29, 2015 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, 2015 at 4:05

2 Answers 2

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, 2015 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, 2015 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, 2015 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, 2015 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, 2015 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.