0

I got a task to display all bash fonts/colors/background colors in table where the text is different for each variation and is being taken from file that contains 448 words/random number(I'm working with numbers). Here is my code for displaying all variations

for i in {0..8}; do for j in {30..37}; do for n in {40..47}; do echo -ne "\e[$i;$j;$n""mcolors" done echo done done echo "" 

Output: enter image description here

Code for generating random numbers:

#!/bin/bash for ((i=0;i<$1;i++)) do echo $RANDOM >> randomnumbers.sh done 

So the question is how can I pass numbers from randomnumbers.sh to my script so "colors" line in output changes to number being taken by order from randomnumbers.sh? Thanks!

4
  • Would it be acceptable to combine both scripts into one? Having two scripts is probably more complicated. By the way: Did you mean | instead of »? » is just a symbol without special meaning, and >> would append the random number to the first script file. Commented Nov 30, 2018 at 17:09
  • Your thinking is flawed. If all you want is to display a random number from randomnumbers.sh which incidentally has a misleading name (as it's just text (a sequence of random numbers, not a shell script), you could just generate it in place. If that's not an option I'd be rewriting the lot. Commented Nov 30, 2018 at 17:11
  • BTW, it'd be much better to take the >> randomnumbers.sh off your echo, and instead put it on the done; that is: for ((i=0; i<$1; i++)); do echo "$RANDOM"; done >randomnumbers -- that way you only open the output file once and keep re-using that single open file descriptor for the whole loop, instead of re-opening the output file hundreds of times (and closing/flushing it after every single write). Commented Nov 30, 2018 at 17:24
  • BTW, see also the APPLICATION USAGE and RATIONALE sections of the POSIX spec for echo (which explicitly states that printf should be used instead if echo would otherwise be passed an argument with backslash-escape sequences or an initial word of -n). Commented Nov 30, 2018 at 18:12

1 Answer 1

2

One simple approach is to have an open file descriptor with your random numbers, and read a line from that file whenever such a value is required.

Here, we're using FD 3, so that other parts of your script can still read from original stdin:

#!/usr/bin/env bash # Make file descriptor 3 point to our file of random numbers (don't use .sh for data files) exec 3< randomnumbers || exit for i in {0..8}; do for j in {30..37}; do for n in {40..47}; do read -r randomNumber <&3 # read one number from FD 3 printf '\e[%s;%s;%sm%05d' "$i" "$j" "$n" "$randomNumber" # & use in the format string done printf '\n' done done printf '\n' 
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks alot! But could you please clarify two things: why do we need to use exec here? And second is what does this line do exactly '%bm%s' ? Is it keys to printf or it does something special? Thanks!
In this usage mode, exec changes the file descriptors for the rest of the script; you could also put 3< randomnumbers on the same line with the done, but my thinking is that that's less readable if you're reading the script from the top to the bottom.
As for %bm%s, the first argument to printf is a format string, and subsequent arguments are values to fill in for the placeholders. Let me show a clearer example...
...okay, see the new version, which shows the value/utility of printf -- using %05d means we're padding out our random numbers so we print them all as exactly 5 digits, so the columns line up again (which they otherwise wouldn't).
...if you had non-numeric strings, you could use %5s to do the same kind of padding (changing the number for the actual length you want, and changing to %-5s if you want to change between left or right justification).
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.