Extracting IP's from a file

I've been trying to work out a way to extract IP's from a file. The IP's are contained withing brackets like this:
[xxx.xxx.xxx.xx]
is there a way to extract just the IP's or at least everything from the starting to ending bracket with grep or something similar?

Thanks in advance.

cat filename | cut -f2 -d [ | cut -f1 -d ] > new_filename

is 'cat' really necessary?

post a sample file and indentify what parts of it you want to extract.

cut -f2 -d [ filename | cut -f1 -d ] > new_filename

this works also... and without the "cat"

That won't work if the ip addresses are interspersed everywhere throughout the file, i.e. if the file looks like this:

foo [999.999.999.991] [999.999.999.992] bar
[999.999.999.993]
foo
[999.999.999.994] foo
foo bar
foo [999.999.999.995]
[999.999.999.996] foo bar [999.999.999.997]

This (clunky) bit should work:

words=$(<file.txt)
for word in $words; do
  echo $word | grep "\[" | awk '{gsub("\[|\]","",$0); print}'
done
999.999.999.991
999.999.999.992
999.999.999.993
999.999.999.994
999.999.999.995
999.999.999.996
999.999.999.997

Still clunky but faster and using shell built-ins and no additional processes

for word in $(<file.txt)
do
    [[ $word != \[* ]] && continue
    word=${word#\[}
    print ${word%\]}
done 

Wierd. I get no results when I use your code:

for word in $(<ip.txt)
do
    if [[ $word = \[* ]]; then
      word=${word#\[}
      print ${word%\]}
    fi
done

But it works if I do

for word in $(<ip.txt)
do
    if [[ $word = \[[0-9]* ]]; then
      word=${word#\[}
      print ${word%\]}
    fi
done

Curious, what shell are you using?

ksh88. I can tell that (for whatever reason) it's not matching $word to \[* but it does match it to \[[0-9]*. The xtrace is showing

[3]+ [[ foo = [* ]]              
[3]+ [[ [999.999.999.991] = [* ]]
[3]+ [[ [999.999.999.992] = [* ]]
[3]+ [[ bar = [* ]]

...which looks like it should match. But it doesn't.

Now I see it. My example was testing for inequality yours is test for equality.

Well, yes. I actually misrepresented your code, which really was:

for word in $(<file.txt)
do
    [[ $word != \[* ]] && continue
    word=${word#\[}
    print ${word%\]}
done

It doesn't return anything for me. If however, I only add the [0-9], as in:

for word in $(<file.txt)
do
    [[ $word != \[[0-9]* ]] && continue
    word=${word#\[}
    print ${word%\]}
done

It works. Why is that?

I don't know why unless our input files are different.

 $ cat file.txt 
foo [999.999.999.991] [999.999.999.992] bar
[999.999.999.993]
foo
[999.999.999.994] foo
foo bar
foo [999.999.999.995]
[999.999.999.996] foo bar [999.999.999.997]

The proof:

{
set -x
for word in $(<file.txt)
do
    [[ $word != \[* ]] && continue
    word=${word#\[}
    print ${word%\]}
done
set +x
}
+ 0< file.txt
+ [[ foo != [* ]]
+ continue
+ [[ [999.999.999.991] != [* ]]
+ word=999.999.999.991]
+ print 999.999.999.991
999.999.999.991
+ [[ [999.999.999.992] != [* ]]
+ word=999.999.999.992]
+ print 999.999.999.992
999.999.999.992
+ [[ bar != [* ]]
+ continue
+ [[ [999.999.999.993] != [* ]]
+ word=999.999.999.993]

That is self evident in your example's case. It should work but I can't answer why mine won't work for you. I too am using KSH88.

That's bizarre. Our input files are identical. Your code gives me:

[1]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ [999.999.999.991] != [* ]]
[3]+ continue                     
[3]+ [[ [999.999.999.992] != [* ]]
[3]+ continue                     
[3]+ [[ bar != [* ]]              
[3]+ continue                     
[3]+ [[ [999.999.999.993] != [* ]]
[3]+ continue                     
[3]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ [999.999.999.994] != [* ]]
[3]+ continue                     
[3]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ bar != [* ]]              
[3]+ continue                     
[3]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ [999.999.999.995] != [* ]]
[3]+ continue                     
[3]+ [[ [999.999.999.996] != [* ]]
[3]+ continue                     
[3]+ [[ foo != [* ]]              
[3]+ continue                     
[3]+ [[ bar != [* ]]              
[3]+ continue                     
[3]+ [[ [999.999.999.997] != [* ]]
[3]+ continue

Maybe I have something set differently?

Update:
It works if I quote the \[:

for word in $(<file.txt)
do
    [[ $word != "\["* ]] && continue
    word=${word#\[}
    print ${word%\]}
done

I was extracting them from an Exim mail log..
cat filename | cut -f2 -d [ | cut -f1 -d ] > new_filename
worked fine for me.