0

Here's the code:

totLines=$(wc -l < extractedips.txt)
for((a=0;a!=$totLines;a++))
{
  head -n$a extractedips.txt | nslookup >> ip_extracted.txt
}

I'm not sure what I'm doing wrong.

that other guy
  • 116,971
  • 11
  • 170
  • 194

3 Answers3

4

Yes! Despite what people are saying, this is a valid bash for loop!

Note, however, that it's a bash extension. It's not a valid sh for loop. You can not use this form of loop in e.g. a shell script declared with #!/bin/sh or run with sh yourscript.

The thing that doesn't work is your for loop contents.

  1. You're trying to get the n'th line, but head -n 42 gets the first 42 lines, not line number 42.
  2. You're using 0-based indexing, while head is 1-based.
  3. You're piping to nslookup, but nslookup expects an argument and not stdin.

The shortest fix to your problem is:

totLines=$(wc -l < extractedips.txt)
for ((a=1; a<=totLines; a++)); do
    nslookup "$(head -n "$a" extractedips.txt | tail -n 1)" >> ip_extracted.txt
done

However, the more efficient and canonical way of doing it is with a while read loop:

while IFS= read -r line
do
  nslookup "$line"
done  < extractedips.txt  > ip_extracted.txt
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • OP, please use the last code of this answer, refered to as _the [...] canonical way of doing it is with a while read loop_. – gniourf_gniourf Apr 23 '14 at 18:06
  • This is it! I found the same thing here: http://stackoverflow.com/questions/5627179/syntax-of-for-loop-in-linux-shell-scripting. I'm still tweaking the code to tailor it to a specific output, but that's it! – user3440108 Apr 23 '14 at 18:28
1

You should use do and done instead of curly braces.

Like this:

totLines=$(wc -l < extractedips.txt)
for ((a=0; a!=totLines; a++)); do
    head -n "$a" extractedips.txt | nslookup >> ip_extracted.txt
done

However, this code will do some weird stuff... Are you trying to pass it line by line into nslookup ?

What about this?

nslookup < extractedips.txt > ip_extracted.txt

Or you might want this:

while read -r line; do
    nslookup "$line" >> ip_extracted.txt
done < extractedips.txt
Aleks-Daniel Jakimenko-A.
  • 10,335
  • 3
  • 41
  • 39
-3

Looks like you need sth. like this

for i in $(cat extractedips.txt)
do
echo $i | nslookup >> ip_extracted.txt
done

You don't need your counter variable, have a look at here for a better understanding.


Why I think your statement is wrong/not what you want and my answer don't deserve a negative voting :)

This statement will echo the first $a lines inside file extractedips.txt

head -n$a extractedips.txt | nslookup >> ip_extracted.txt

First up you have a file with ip's

cat extractedips.txt
127.0.0.1
192.168.0.1
173.194.44.88

Now we if you do

for a in 1 2 3
    head -n$a
done

the script will output

127.0.0.1
127.0.0.1
192.168.0.1
127.0.0.1
192.168.0.1
173.194.44.88

But I guess you need a list with all all ip's only once. If you don't need duplicate ip's you could also remove them. This will give you a sorted list with duplicates removed.

for a in $(sort test.txt | uniq -u)
do
echo $a | nslookup >> ip_extracted.txt
done

Update

As Aleks commented this will not work if the text file contain a '*' char. The shell will expand all files in current directory and echo the filename. I didn't know that :/

cb0
  • 8,415
  • 9
  • 52
  • 80