This question already has answers here:
Brace expansion with a Bash variable - {0..$foo}
(5 answers)
Closed 1 year ago.
I'm having a hard time figuring out how to use a $var inside curly braces {}..
#!/bin/bash
read -p "How many files must there be built?" numb
for n in {1..$numb}
do
echo "Building file $n"
touch file$n.txt
done
This would result in:
How many files must there be built?8
Building file {1..8}
I've tried enclosing the $numb inside backticks or double quotes but to no avail..
You could use this syntax for your loop:
#!/bin/bash
read -p "How many files must there be built?" numb
for ((i=1; i<=$numb; i++)); do
echo "Building file $i"
touch file$i.txt
done
It's less fancy, but it works.
Related
This question already has answers here:
Brace expansion with a Bash variable - {0..$foo}
(5 answers)
Closed 3 years ago.
I am trying to use command line arguments for arithmetic but cant seem to find any documentation explaining how to do this. As an example if I use:
for i in {$1..$2}
do
echo $i
done
and call
test.sh 1 20
the following output is produced:
{1..20}
instead of
1
2
3
..
20
The following will also work:
declare -a ary='({'$1..$2'})'
for i in "${ary[#]}"; do
echo "$i"
done
Note that declare is as harmful as eval.
You need to check and sanitize the arguments before use.
There's no way to do this properly without the evil eval() with brace expansion in bash.
You can use seq instead :
for i in $(seq $1 $2); do
This question already has answers here:
bash variable interpolation separate variables by a hyphen or underscore
(3 answers)
Error in string Concatenation in Shell Scripting
(3 answers)
Closed 5 years ago.
I am using MacBook pro terminal to execute a shell script. It loops through a text file and create filenames based on each line in the file.
#!/bin/bash
year=2010
list=list_test.txt
mydir=thisdir
i=1 # counter
while read line
do
echo $i $line
file1=`echo $mydir/file_$year_$line_test.tif`
file2=`echo $mydir/file_$year_$line_test.tif`
echo $file1 $file2
i=$(($i+1))
done < $list
However, the output is peculiar:
1 17019
thisdir/file_.tif thisdir/file_.tif
2 17029
thisdir/file_.tif thisdir/file_.tif
3 17039
thisdir/file_.tif thisdir/file_.tif
Within the loop, bash does not recognize some variables, like "year" which is a global, and "line" which is read from the text file. The text file is as below:
17019
17029
17039
Another script with exactly the same manner works very well. This is mysterious to me now.
Any help or comments are extremely appreciated! Thanks very much!
_ is a valid character for an identifier, but you want to use it as a literal character in the file name. You need to use the full form of parameter expansion, ${x} instead of $x.
(Also, the command substitution isn't necessary.)
file1=$mydir/file_${year}_${line}_test.tif
file2=$mydir/file_${year}_${line}_test.tif
This question already has answers here:
Dynamic variable names in Bash
(19 answers)
What is indirect expansion? What does ${!var*} mean?
(6 answers)
Lookup shell variables by name, indirectly [duplicate]
(5 answers)
Closed 5 years ago.
Say I have two variables;
var_one_string=foo
var_two_string=bar
How would I accomplish something like this (pseudo code examples);
EXAMPLE 1
for i in one two; do
echo $var_${i}_string
done
# Desired output
foo
bar
EXAMPLE 2
for i in one two; do
echo $var_$(echo ${i})_string
done
# Desired output
foo
bar
I understand that this is bad substitution, I am just wondering if there is a way to nest a string within another variable call?
EDIT: I was able to get it to work
var_one_string=foo
var_two_string=bar
for i in $(echo ${!var_*}); do
echo ${!i}
done
foo
bar
Use the declare built-in along with indirect-variable expansion in bash. First define the elements of for the dynamic nature in an array as
#!/bin/bash
list=(one two)
unset count
for var in "${list[#]}"; do
declare var_${var}_string="string"$((++count))
done
and now access the created variables using indirect expansion
for var in "${list[#]}"; do
dymv="var_${var}_string"
echo "${!dymv}"
done
and never use eval for this requirement. Could be dangerous because of unlikely code-injection possibility with a harmful command.
Basically, you can use eval: echo $(eval '$var_'"${i}")
But you can also use a dictionnary:
declare -A vars
vars=( ["one"]="number-one" ["two"]="number-two" )
i="one"
echo "${vars[${i}]}"
This question already has answers here:
Check if a file exists with a wildcard in a shell script [duplicate]
(21 answers)
Closed 6 years ago.
I wish to be able to check if file exist.
if [ -f "/var/run/screen/user/*.$InstanceName" ]; then
echo -e "screen instance exist"
fi
but the wilcard / joker don't work
How I can pass it ?
Your wildcard doesn't work because it's quoted. Unquoting it however might break the [ command as it only expects one filename argument, and if two or more files wore globbed it would break.
In bash you can use compgen that will generate a list of files matching the globbing pattern, it will also set proper exit status if no globs are found, it is a hack? I don't know, but it could look like it:
if compgen -G "/var/run/screen/user/*/$InstanceName" > /dev/null; then
printf "screen instance exist\n"
fi
This question already has answers here:
I just assigned a variable, but echo $variable shows something else
(7 answers)
Closed 6 years ago.
Can anyone tell me why the following:
#!/bin/bash
TEST=$(echo '*** this is a test ***')
echo $TEST
...outputs a listing of the current directory, then "this is a test", then another listing of the current directory?
Background: I have some output that I'm putting in a variable, and then I want to do several different greps on the contents of that variable, but the echo is inserting all this extra stuff that shouldn't be there.
This is on OS X 10.11.4.
globbing in action! * expands in the second echo. You have to double quote it to prevent expansion.
echo "$TEST"
see this for a related answer