This question already has answers here:
Closed 8 months ago.
I am still learning how to shell script and I have been given a challenge to make it easier for me to echo "Name1" "Name2"..."Name15" and I'm not too sure where to start, I've had ideas but I don't want to look silly if I mess it up. Any help?
I haven't actually tried anything just yet it's all just been mostly thought.
#This is what I wrote to start
#!/bin/bash
echo "Name1"
echo "Name2"
echo "Name3"
echo "Name4"
echo "Name5"
echo "Name6"
echo "Name7"
echo "Name8"
echo "Name9"
echo "Name10"
echo "Name11"
echo "Name12"
echo "Name13"
echo "Name14"
echo "Name15"
My expected results are obviously just for it to output "Name1" "Name2" etc. But I'm looking for a more creative way to do it. If possible throw in a few ways to do it so I can learn. Thank you.
The easiest (possibly not the most creative) way to do this is to use printf
:
printf "%s\n" name{1..15}
This relies on bash brace expansion {1..15}
to have the 15 strings.
Use a for loop
for i in {1..15};do echo "Name$i";done
A few esoteric solutions, from the least to the most unreasonable :
The weird chain is your expected result encoded in base64, an encoding generally used to represent binary data as text. base64 -d <<< weirdChain
is passing the weird chain as input to the base64
tool and asking it to decode it, which displays your expected result
generate an infinite stream of "Name", truncate it, use line numbers :
yes Name | awk 'NR == 16 { exit } { printf("%s%s\n", $0, NR) }'
yes
outputs an infinite stream of what it's passed as argument (or y
by default, used to automatize interactive scripts asking for [y/n] confirmation). The awk
command exits once it reaches the 16th line, and otherwise prints its input (provided by yes
) followed by the line number. The truncature could as easily be done with head -15
, and I've tried using the nl
"number line" utility or grep -n
to number lines, but they always added the line numbers as prefix which required an extra re-formatting step.
read random binary data and hope to stumble on all the lines you want to output :
timeout 1d strings /dev/urandom | grep -Eo "Name(1[0-5]|[1-9])" | sort -uV
strings /dev/urandom
will extract ascii sequences from the binary random source /dev/urandom, grep
will filter those which respect the format of a line of your expected output and sort
will reorder those lines in the correct order. Since sort
needs to have a received its whole input before it reorders it and /dev/urandom
won't stop producing data, we use timeout 1d
to stop reading from /dev/urandom
after a whole day in hope it has sifted through enough random data to find your 15 lines (I'm not sure that's even remotely likely).
use an HTTP client to retrieve this page, extract the bash script you posted and execute it.
my_old_script=$(curl "https://stackoverflow.com/questions/57818680/" | grep "#This is what I wrote to start" -A 18 | tail -n+4)
eval "$my_old_script"
curl
is a command line tool that can be used as an HTTP client, grep
with its -A 18
parameter will select the "This is what I wrote to start" text and the 18 lines that follow, tail
will remove the first 3 lines, and eval
will execute your script.
While it will be much more efficient than the previous solution, it's an even less reasonable solution because high-rep users can edit your question to make this solution execute arbitrary code on your computer. Ideally you'd be using an HTML-aware parser rather than basic string manipulation to extract the code, but we're not talking about best practices here...