0

I have a bash script where I'm using a for loop to generate a list of numbers (increasing by one).

Within my loop I use echo in combination with tee to build out my string.

I then use sed to take my "list" (input as file) of numbers and then format it.

Since I use a for loop to generate this list (text file), is there a better and more efficient way for me to create my string (it's being appended as it's being looped) to include values double quoted without having to write to a file first?

Here's my code:

#!/usr/local/bin/bash

if [[ $# != 3 ]]; then
   echo "Usage:   ./crIPRange.sh <octet> <start#> <ending#>" 2>&1
   echo "Example: ./crIPRange.sh 10.1.2 100 150" 2>&1
   exit 1
fi

_octet="$1"
_startIP="$2"
_IPList="List1.out"
_IPListFinal="List2.out"

for (( c=$2; c<=$3; c++ ))
do
  echo "${_octet}.$c" | tee >> ${_IPList}
  sed -E 's/^(.*)$/"\1"/' ${_IPList} | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g' |  tee > ${_IPListFinal}
done

In other words, I'm thinking I don't necessarily need that step of writing it to a file as a list?

So in the end, I have (2) output files and I really just need my final output. Would I use something like printf?

1 Answer 1

1

This looks like a brutally complicated way to make a comma separated list. For every single entry, your sed command goes through the complete file, just to replace a single newline by a comma. Moving sed to outside the loop and executing it just once would already improve efficiency a bit.

But you don't need sed at all (and no intermediate files, at that). This solution populates an array with the elements we want, then prints it as a single string with IFS set to a comma:

#!/bin/bash

(( $# != 3 )) && echo "Wrong number of arguments" >&2

subnet=$1
from=$2
to=$3

for (( i = from; i <= to; ++i )); do
    arr+=("\"$subnet.$i\"")
done

IFS=,

echo "${arr[*]}"

Notice that your comparison if [[ $# != 3 ]] uses the != meant for strings, but should use -ne for numbers. Or even easier, (( )) made for exactly that.

Usage and output:

$ ./octet 1.2.3 10 15
"1.2.3.10","1.2.3.11","1.2.3.12","1.2.3.13","1.2.3.14","1.2.3.15"

Or, if you don't want a function, you can just use brace expansion and tr:

$ echo \"1.2.3.{10..15}\" | tr ' ' ,
"1.2.3.10","1.2.3.11","1.2.3.12","1.2.3.13","1.2.3.14","1.2.3.15"

This cannot be parameterized, though.

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

4 Comments

It was a hack as it always is as i'm learning to script. Appreciate the input. Thanks for pointing out the bad practice as well as providing an alternative solution.
How do I double quote the output?: "1.2.3.10","1.2.3.11","1.2.3.12"
@noober Updated. Notice (for future reference) that it's good practice to show example input and expected output in your questions – then people don't have to guess the intention of the provided code.
will do for future reference. thanks for your input!

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.