2

I have string looks likes this

string="xxxxx.yyyyy[2].zzzzz"

I want to extract the number between the [ ]. I used the following awk command

echo $string | awk -F'[]' '{print $2}'

But this awk command returns error:

awk: bad regex '[]': Unmatched [ or [^

How to fix that?

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
MOHAMED
  • 41,599
  • 58
  • 163
  • 268

4 Answers4

6

This should work:

echo "xxxxx.yyyyy[2].zzzzz" | awk -F '[][]' '{print $2}'
2

Order of ] before [ inside character class is important here.

This shall also work by double escaping [ and ] using alternation regex:

echo "xxxxx.yyyyy[2].zzzzz" | awk -F '\\[|\\]' '{print $2}'
2

OR:

echo "xxxxx.yyyyy[2].zzzzz" | awk -F '[\\[\\]]' '{print $2}'
2
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • 1
    +1 I'm surprised that the `][` are interpreted as part of one character class, rather than the whole thing being interpreted as two empty classes. Another option would be to use `']|\\['`. – Tom Fenech Nov 06 '14 at 11:14
  • @TomFenech I have seen it someplace in the `awk` manual that best way to get the brackets, is the `-F'[][]'` – Jotne Nov 06 '14 at 11:28
  • Or with double quote: `awk -F "\\\[|\\\]" '{print $2}'` or `awk -F "[][]" '{print $2}'` – Jotne Nov 06 '14 at 11:30
  • 1
    @TomFenech its specifically defined by awk language that if you want `]` in a bracket expression (it's not a character class) it must be the first character or be escaped `\]`. Other characters that have meaning for bracket expressions (e.g. `-` as used in a range like `0-9`) have similar requirements on position/escaping within the expression. – Ed Morton Nov 06 '14 at 13:57
0

With sed:

echo "xxxxx.yyyyy[2].zzzzz" | sed -r 's/.*\[(.*)\].*/\1/g'

With awk:

 echo "xxxxx.yyyyy[2].zzzzz" | awk 'BEGIN {FS="[";RS="]"} {print $2}'
Arjun Mathew Dan
  • 5,240
  • 1
  • 16
  • 27
0

With grep

echo "xxxxx.yyyyy[2].zzzzz" | grep -oE '[0-9]'

2
Arnab Nandy
  • 6,472
  • 5
  • 44
  • 50
0

Here is a more generic approach. It will get any number out of a text file:

echo "xxxxx.yyyyy[2].zzzzz" | awk -F "[^0-9]*" '{for (i=2;i<=NF;i++) printf "%s%s",$i,(i==NF?RS:" ")}'
2

Other example

cat file
"C 56","Home athletics center","LAC"
"D001","50M Run","50M"
"D003","10.505M Run","100M","42K"

awk -F "[^0-9.]*" '{for (i=2;i<=NF;i++) printf "%s%s",$i,(i==NF?RS:" ")}' file
56
001 50 50
003 10.505 100 42
Jotne
  • 40,548
  • 12
  • 51
  • 55