$ bash argcnt.sh this is a "real live" test
is
real live
(to display only paired arguments)
Because, I know only in this way:
#!/bin/bash
echo "$2"
echo "$4"
It seems like you want to print every other argument given to the script. You could then create a loop over $#:
#!/bin/bash
# idx will be 2, 4, 6 ... for as long as it's less than the number of arguments given
for ((idx = 2; idx < ${##}; idx += 2))
do
# variable indirection below:
echo "${!idx}"
done
Note: You can use $# instead of ${##} to get the number of elements in $# too. I don't know which one that is preferred by people in general.
If what you want is print every other argument, starting from the second, you can use shift:
$ cat argcnt
#!/bin/bash
while shift; do printf '%s\n' "$1"; shift; done
$ ./argcnt this is a "real live" test foo
is
real live
foo
Related
I am currently trying to rename an input argument by the variable "i" in the following for loop:
cd $1
num=$(echo $#)
echo $num
echo $#
echo "This is the next part where I print stuff"
for i in $(seq 2 $num)
do
echo $i
echo ${!i}
Args_array+=$(printf '${arg_%s[#]}' ${i})
echo $Args_array
arg_${i}=$(ls ${!i})
done
The output is as follows:
4
output_folder /path/to/my.tsv /path/to/my2.tsv /path/to/my3.tsv
2
/path/to/my.tsv
${arg_2[#]}
/var/spool/slurm/d/job6985121/slurm_script: line 23: arg_2=/path/to/my.tsv: No such file or directory
But it will not allow me to rename the $2, $3 arguments with "i" like this. Any help would be appreciated.
I want to pass these arguments into R and have to put them in arg_1, arg_2, etc. format.
Not sure I understand what's being attempted with Args_array so focusing solely on OP's comment: 'have to put them in arg_1, arg_2' and skipping arg_1 since OP's code doesn't appear to care about storing $1 anywhere; then again, is R not capable of processing input parameters from the command line?
One bash idea:
$ cat testme
#!/usr/bin/bash
num=$#
for ((i=2;i<=$num;i++))
do
declare args_$i=${!i}
done
for ((i=2;i<=$num;i++))
do
typeset -p args_$i
done
Taking for a test drive:
$ testme output_folder /path/to/my.tsv /path/to/my2.tsv /path/to/my3.tsv
declare -- args_2="/path/to/my.tsv"
declare -- args_3="/path/to/my2.tsv"
declare -- args_4="/path/to/my3.tsv"
I know that if I do print ("f" + 2 * "o") in python the output will be foo.
But how do I do the same thing in a bash script?
You can use bash command substitution to be more portable across systems than to use a variant specific command.
$ myString=$(printf "%10s");echo ${myString// /m} # echoes 'm' 10 times
mmmmmmmmmm
$ myString=$(printf "%10s");echo ${myString// /rep} # echoes 'rep' 10 times
reprepreprepreprepreprepreprep
Wrapping it up in a more usable shell-function
repeatChar() {
local input="$1"
local count="$2"
printf -v myString '%*s' "$count"
printf '%s\n' "${myString// /$input}"
}
$ repeatChar str 10
strstrstrstrstrstrstrstrstrstr
You could simply use loop
$ for i in {1..4}; do echo -n 'm'; done
mmmm
That will do:
printf 'f'; printf 'o%.0s' {1..2}; echo
Look here for explanations on the "multiplying" part.
In bash you can use simple string indexing in a similar manner
#!/bin/bash
oos="oooooooooooooo"
n=2
printf "%c%s\n" 'f' ${oos:0:n}
output
foo
Another approach simply concatenates characters into a string
#!/bin/bash
n=2
chr=o
str=
for ((i = 0; i < n; i++)); do
str="$str$chr"
done
printf "f%s\n" "$str"
Output
foo
There are several more that can be used as well.
You can create a function to loop a string for a specific count and use it in the
loop you are executing with dynamic length. FYI a different version of oter answers.
line_break()
{
for i in `seq 0 ${count}`
do
echo -n "########################"
done
}
line_break 10
prints: ################
I'm recently learning bash and confused when a variable would add $. I find code like:
i=1
while [ $i -le 10 ]
do
echo "$n * $i = `expr $i \* $n`"
i=`expr $i + 1`
done
The $ substitutes the variable. Writing $i will insert the value of i, no matter where you write it.
If you want to assign to the variable, that obviously makes no sense.
I thought #slaks' [ answer ] wouldn't be complete without this :
When not to add $ for a variable
With The Double-Parentheses [ Construct ]
x=5;
(( x++ )) # fine, note this construct accept $x form too.
When using export
var=stuff
export var #fine
When using declare
declare -a arry # fine
When not omit $
As #rici pointed out in the comment below:
you can leave out the $ in any arithmetic context, not just ((...))
and $((...)) ... For example, if arr is an array (not associative), then
${arr[x++]} is also fine.
Consider
# You wanted to create an associative array 'test' but you forgot to do
# declare -A test , Now below
test[foo]=bar # is foo a variable or a key, the reader isn't clear
# creates a simple array
echo ${test[foo]} # is foo a variable or a key?
bar
declare -p test
declare -a test='([0]="bar")'
# What happened?
# Since foo was not set at the point when 'test[foo]=bar' was called,
# bash substituted it with zero
# I meant to say test[foo]=bar hides an error.
A key thing to remember is that variables are never passed around in shell, only values. When you call something like
echo "$foo"
you might think that echo receives $foo, then looks at its value. Instead, the shell first expands $foo to the value of foo, then passes that value to echo.
The dollar sign is used to introduce any such parameter expansion, where the value of a parameter is needed. Consider:
$ foo=10
$ echo foo
foo
$ echo $foo
10
From the perspective of the echo command, there is no difference between echo $foo and echo 10; in both cases, the value passed to echo is 10.
To set a value to a variable in bash you can do
a=10
Where as to access the value of that variable you need to use
echo $a which mean $ is a symbol used to access the value of a variable.
i=1 ---> setting variable as 1
while [ $i -le 10 ] ---> simple while statement which loops till value of i is less that 10
do
echo "$n * $i = `expr $i \* $n`" ---> This is a syntax error bcoz value of n is never assigned
i=`expr $i + 1` ---> This line add's one to value of i
done ---> terminate while loop
Hope that explains you.
I need to get three arguments by test.ksh script
as the following
./test.ksh 12 34 AN
is it possible to set the argument by counter for example ?
for get_arg 1 2 3
do
my_array[get_arg]=$$get_arg
print ${my_array[get_arg]}
done
in this example I want to get three arguments from the user by loop counter "$$get_arg"
in place of $1 $2 $3
is it possible? and how ?
my_array=("$#")
for i in 0 1 2
do
echo "${my_array[$i]}"
done
This assigns all the arguments to array my_array; the loop then selects the first three arguments for echoing.
If you're sure you want the first three arguments in the array, you could use:
my_array=("$1" "$2" "$3")
If you want the 3 arguments at positions 1, 2, 3 in the array (rather than 0, 1, 2), then use:
# One or the other but not both of the two assignments
my_array=("dummy" "$#")
my_array=("dummy" "$1" "$2" "$3")
for i in 1 2 3
do
echo "${my_array[$i]}"
done
bash has a special variable
$#
which contains the arguments of the script it currently executes. I think this is what your'e looking for:
for arg in $# ; do
# code
done
Edit:
My bad ksh:
for arg;do
print $arg
done
Original Post:
Use shift to iterate through shell script parameters:
# cat test.sh
#!/bin/bash
while [ "$1" != "" ]; do
echo $1
shift
done
test run:
# ./test.sh arg1 monkey arg3
arg1
monkey
arg3
source
Even you don't need in $#, this would work the same:
#!/bin/bash
i=0
for arg; do
my_array[i]="$arg"
echo "${my_array[i]}"
(( i++ ))
done
That is,
if in words is not present, the for command executes the commands
once for each positional parameter that is set, as if in $# had been
specified.
So I was working on a project tonight and assumed based on my poor understanding that the requirement was to create a script to take a number and count down to 1 with commas on the same line.
A few people here introduced me to the seq command and I was on my way.
Turns out it needs to take the variable integer from a command line argument.
What I have now:
#!/bin/bash
#countdown
read -p "Enter a Number great than 1: " counter
seq -s, $counter -1
Needs to work by taking an argument after the line, such as /assign1p1 5 and then outputting 5,4,3,2,1
I've seen the $1 used as an argument marker? Is that how to work from it?
Use Three Arguments
The correct call to seq for your use case is:
seq [OPTION]... FIRST INCREMENT LAST
To decrement your starting value down to 1 using the defined separator, try something similar to this example:
$ set -- 5
$ seq -s, $1 -1 1
5,4,3,2,1
Obviously, the call to set won't be needed inside the script, but is a great way to test at the command line.
The command-line arguments passed to your script are $1, $2, etc.
#!/bin/bash
seq -s, $1 1
echo
If you want to make this more robust you might want to verify that the user passed in the correct number of arguments, which is the variable $#.
#!/bin/bash
if (( $# != 1 )); then
echo "Usage: $0 num" >&2
exit 1
fi
seq -s, $1 1
echo
Arguments passed to the script from the command line include : $0, $1, $2, $3 . . .
$0 is the name of the script itself, $1 is the first argument, $2 the second, $3 the third, and so forth. [2] After $9, the arguments must be enclosed in brackets, for example, ${10}, ${11}, ${12}.
If for whatever reason you do not want to use seq
a=$1
for (( b = a; b > 0; b-- ))
do
(( b == a )) || printf ,
printf $b
done