1

Trying to print range of ip addresses to a file. Instead of looping through the range it just prints one line containing the variable values.

http://tpcg.io/0lCSJr

cidr="192.168.0.1/24"

# range is bounded by network (-n) & broadcast (-b) addresses.
lo=$(ipcalc -n $cidr |cut -f2 -d=)
hi=$(ipcalc -b $cidr |cut -f2 -d=)

read a b c d <<< $(echo $lo |tr . ' ')
# echo $a.$b.$c.$d
read e f g h <<< $(echo $hi |tr . ' ')
# echo $e.$f.$g.$h


for ip in {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h};
do
    echo $ip > results.txt
done;

Current output is...

{192..192}.{168..168}.{0..0}.{0..255}

If given 192.168.0.1/24 looking for how to get the output to print each host in that network on each line in a file...

192.168.0.0
192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
...
192.168.0.255
8
  • 1
    Please add your desired output for that sample input to your question. Commented Feb 22, 2019 at 20:05
  • 1
    {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h} will not work because brace expansion does not accept variables as arguments. Commented Feb 22, 2019 at 20:08
  • brace expansion and variables don't work without eval Commented Feb 22, 2019 at 20:09
  • See BashPitfalls #33 Commented Feb 22, 2019 at 20:11
  • 2
    right, but beware of eval risks if the content is not under your control. Commented Feb 22, 2019 at 20:27

2 Answers 2

1

This usage of seq and xargs looks cool and funny:

seq 192 192 |
xargs -i seq -f "{}.%.0f" 168 168 |
xargs -i seq -f "{}.%.0f" 0 0 |
xargs -i seq -f "{}.%.0f" 0 255

So in your script that would be:

seq $a $e |
xargs -i seq -f "{}.%.0f" $b $f |
xargs -i seq -f "{}.%.0f" $c $g |
xargs -i seq -f "{}.%.0f" $d $h |
while read ip; do
   ...
done

or you could for ip in $(seq $a $e | .... ); do, but that would be less cool.

What's good, it's easy to make it a function.

Sign up to request clarification or add additional context in comments.

Comments

0

This works...it writes all the ip addresses to a file using eval instead of the loop and then I split them by space and replace the space with newline into another file.

cidr=$1

# range is bounded by network (-n) & broadcast (-b) addresses.
lo=$(ipcalc -n $cidr |cut -f2 -d=)
hi=$(ipcalc -b $cidr |cut -f2 -d=)

read a b c d <<< $(echo $lo |tr . ' ')
echo $a.$b.$c.$d
read e f g h <<< $(echo $hi |tr . ' ')
echo $e.$f.$g.$h

eval "echo {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h}" > ip_range.txt

tr ' ' '\n' < ip_range.txt > results.txt

Also you could do this instead and edit the spacing in one go...

cidr=$1

# range is bounded by network (-n) & broadcast (-b) addresses.
lo=$(ipcalc -n $cidr |cut -f2 -d=)
hi=$(ipcalc -b $cidr |cut -f2 -d=)

read a b c d <<< $(echo $lo |tr . ' ')
echo $a.$b.$c.$d
read e f g h <<< $(echo $hi |tr . ' ')
echo $e.$f.$g.$h

eval "printf '%s\n' {$a..$e}.{$b..$f}.{$c..$g}.{$d..$h}" > ip_range.txt

1 Comment

tr ' ' '\n' ? Why not print newline the first time? eval "printf '%s\n' {$a.. ...."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.