0

With this I can callmyscrip.sh 100 and this will print 100 rows with the content generated by seq, but what's the best way to separate the content TEXT="xxx yyy ${this}" for readability with a variable?

#!/bin/bash
howmanytimes=$1
for this in $(seq -w ${howmanytimes}); do echo " /
-- ${this}

"; done

this instead would not work as $this isn't replaced:

#!/bin/bash
howmanytimes=$1
TEXT="THIS WOULD NOT WORK: ${this}"
for this in $(seq -w ${howmanytimes}); do echo ${TEXT} ; done
export $TEXT
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
user2239318
  • 2,578
  • 7
  • 28
  • 50

4 Answers4

1

seq(1) is nonstandard, inefficient and useless.

Check http://mywiki.wooledge.org/BashGuide/TestsAndConditionals#Conditional_Loops

With :

#!/bin/ksh

txt='this should work with int: '
for i in {0..$1}; do
    echo "$txt $i"
done

With :

#!/bin/bash

txt='this should work with int: '
for ((i=0; i<=$1; i++)) {
    echo "$txt $i"
}
Gilles Quénot
  • 173,512
  • 41
  • 224
  • 223
  • `seq` is **not** inefficient. `printf '%s' "$txt "; seq -s $'\n'"$txt " "$1"` is more efficient than using a C-style `for` loop in `bash`. – M. Nejat Aydin Feb 16 '23 at 09:01
1

You can wrap your dynamic text in a bash function:

#!/bin/bash

get_content() {
    echo "THIS WOULD WORK: $1"
}

how_many_times=$1

for i in $(seq -w ${how_many_times}); do
    echo "$(get_content $i)"
done

If you just need to output the content, can simplify it like this:

#!/bin/bash

get_content() {
    echo "THIS WOULD WORK: $1"
}

how_many_times=$1

for i in $(seq -w ${how_many_times}); do
    get_content $i
done
yolenoyer
  • 8,797
  • 2
  • 27
  • 61
1

You can use printf directly, and skip the loop entirely:

#!/bin/bash
howmanytimes=$1
text="This WILL work: %s"
printf "${text}\n" $(seq -w ${howmanytimes})

Note that \n needs to be added to the format string, since printf doesn't add a newline automatically like echo does. If you want additional newlines (like in the example), you can add them as either \n or actual newlines, in either the format variable or where it's used in the printf argument. Also, if you want to include a literal backslash or percent sign in the string, double it (i.e. %% to print %, or \\ to print \).

BTW, since printf is a bash builtin, it's not subject to the normal argument list length limits, so this'll work even with very large numbers of numbers.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151
0

Check your script with shellcheck. printf is a simple template language. I could see:

#!/bin/bash
howmanytimes=$1
text="THIS WOULD WORK: %s"
for this in $(seq -w "${howmanytimes}"); do
   printf "$text" "$this"
done

You could use envsubst to replace environment, however in this case printf looks way clearer. Research quoting in shell.

#!/bin/bash
howmanytimes=$1
text='THIS WOULD WORK: ${THIS}'
for this in $(seq -w "${howmanytimes}"); do
   THIS="$this" envsubst <<<"$text"
done
KamilCuk
  • 120,984
  • 8
  • 59
  • 111