How to echo arguments in loop in bash - linux

I have a bash that should be run in this way:
./script.sh <arg1> <arg2> <arg3>...<argn>
I want to show these args in my bash:
<arg3> <arg4> ... <argn>
So I wrote this bash:
for (( i=1; i<=$#-3; i++ ))
do
echo $((3+i))
done
but it shows me number of args.
How can I put # in order to see my real args?
Thanks

If you want to show arguments starting from arg3, you can simply use
echo "${#:3}" # OR
printf "%s\n" "${#:3}"
If you really want to show argument indices, use
for (( i=3; i < $#; i++)); do
echo $i
done

You can store all arguments in a BASH array and then use them for processing later:
args=( "$#" )
for (( i=2; i<${#args[#]}; i++ ))
do
echo "arg # $((i+1)) :: ${args[$i]}"
done

A minimal solution that displays the desired arguments without the math:
shift 2
for word
do
echo ${word}
done

I prefer #anubhava's solution of storing the arguments in an array, but to make your original code work, you could use eval:
for ((i=1;i<=$#;i++)); do
eval echo "\$$i"
done

After your all good answers I found this solution that works well for my thread:
ARG=( $(echo "${#:3}") )
for (( i=1; i<=$#-3; i++ ))
do
echo ${ARG[i]}
done

Related

bash script array variables in for loop

I am trying to write bash script that get 3 arguments of paths.
for ex /tmp/1 /tmp/2 /tmpnew
I want to iterate over the argument except the last one and each time copy the file to the path of the last argument.
I have problem with echo '${files[$(($len))]}' inside the for. I cant pull the last argument like that.
files=( "$#" )
len=${#files[#]}
echo $len
for (( i=0; i<$(( $len -1 )); i++ ))
do
echo ${files[$(($len))]}
echo ${files[$i]}
done
The last element is ${files[len-1]}, or simply ${files[-1]}.
Similarly, you can use just ${files[i]}. If the array is not associative, bash interprets the index as an arithmetic expression.
#!/bin/bash
files=("$#")
len=${#files[#]}
echo $len
for (( i=0; i<len-1; i++ )) ; do
echo "${files[-1]}"
echo "${files[i]}"
done

How to add called variable as a suffix to another variable and then call the suffixed variable?

My script:
for (( i=1; i <= $j; i++ ))
do
list_$i = $i
echo "$list_$i"
done
Expected output:
1
2
3
.
.
.
etc
I have a problem with the echo statement while calling the variable.
Please help me on this.
Assuming that $j has an nonnegative integral value,
for (( i=1; $i<=$j; i=$i+1 ))
do
list[$i]=$i
echo "${list[$i]}"
done
Bash arrays are used, whereby $list is a single structure, a Bash array.
First remember that a variable assignment is without spaces around the =.
What you are trying to do, is possible but complicated.
for (( i=1; i <= 6; i++ )); do
source <(echo "list_$i=$i")
varname=list_$i
echo "${!varname}"
done
You can also view the results in a different loop
for result in list_{1..6}; do
echo "${result}=${!result}"
done

Checking if array element is empty with for loop in bash

Can you please provide a sample code for checking if array element is empty using for loop?
None of this worked for me:
declare -a f=( 'file' )
for ((i=0; ${f[$i]}; i++); do echo "i: $i"; done
for ((i=0; `test -n "${f[$i]}"`; i++); do echo "i: $i"; done
What I wanted is to keep this braces-like for style and iterate over array, following solution worked for me:
for((i=0; i < ${#f[#]}; i++))
Does any other syntax available?
This might work
for i in ${f[#]}
do
if [ -z "$f[$i]" ]
then
#do whatever you want
fi
done

How can I look up a variable by name with #!/bin/sh (POSIX sh)?

f1="filename1";
i=1;
c=f$i
echo $c
What shell command should I use so that echo $c returns "filename1" as the output?
Use variable indirection.
#!/bin/bash
f1="filename1";
i=1;
c=f$i
echo ${!c}
It works in bash ( GNU bash, version 4.1.2(1)-release ). I have not tried in other shells.
You can use eval to "nest" variable substitutions.
f1="filename1";
i=1;
eval c=\${f$i}
echo $c
Reusable function
# Expand the variable named by $1 into its value. Works in both {ba,z}sh
# eg: a=HOME $(var_expand $a) == /home/me
var_expand() {
if [ -z "${1-}" ] || [ $# -ne 1 ]; then
printf 'var_expand: expected one argument\n' >&2;
return 1;
fi
eval printf '%s' "\"\${$1?}\""
}
It warns when given:
Null input
More than one argument
A variable name which isn't set
Avoid intensive operations like eval. Use an associative array.
#!/bin/bash
typeset -A c
c[f1]=filename1
i=1
echo ${c[f$i]}

concatenate inputs in bash script [duplicate]

This question already has answers here:
Concatenate all arguments and wrap them with double quotes
(6 answers)
Closed 5 years ago.
I would like to concatenate all the arguments passed to my bash script except the flag.
So for example, If the script takes inputs as follows:
./myBashScript.sh -flag1 exampleString1 exampleString2
I want the result to be "exampleString1_exampleString2"
I can do this for a predefined number of inputs (i.e. 2), but how can i do it for an arbitrary number of inputs?
function concatenate_args
{
string=""
for a in "$#" # Loop over arguments
do
if [[ "${a:0:1}" != "-" ]] # Ignore flags (first character is -)
then
if [[ "$string" != "" ]]
then
string+="_" # Delimeter
fi
string+="$a"
fi
done
echo "$string"
}
# Usage:
args="$(concatenate_args "$#")"
This is an ugly but simple solution:
echo $* | sed -e "s/ /_/g;s/[^_]*_//"
You can also use formatted strings to concatenate args.
# assuming flag is first arg and optional
flag=$1
[[ $1 = ${1#-} ]] && unset $flag || shift
concat=$(printf '%s_' ${#})
echo ${concat%_} # to remove the trailing _
nJoy!
Here's a piece of code that I'm actually proud of (it is very shell-style I think)
#!/bin/sh
firsttime=yes
for i in "$#"
do
test "$firsttime" && set -- && unset firsttime
test "${i%%-*}" && set -- "$#" "$i"
done
IFS=_ ; echo "$*"
I've interpreted your question so as to remove all arguments beginning with -
If you only want to remove the beginning sequence of arguments beginnnig with -:
#!/bin/sh
while ! test "${1%%-*}"
do
shift
done
IFS=_ ; echo "$*"
If you simply want to remove the first argument:
#!/bin/sh
shift
IFS=_ ; printf %s\\n "$*"
flag="$1"
shift
oldIFS="$IFS"
IFS="_"
the_rest="$*"
IFS="$oldIFS"
In this context, "$*" is exactly what you're looking for, it seems. It is seldom the correct choice, but here's a case where it really is the correct choice.
Alternatively, simply loop and concatenate:
flag="$1"
shift
the_rest=""
pad=""
for arg in "$#"
do
the_rest="${the_rest}${pad}${arg}"
pad="_"
done
The $pad variable ensures that you don't end up with a stray underscore at the start of $the_rest.
#!/bin/bash
paramCat () {
for s in "$#"
do
case $s in
-*)
;;
*)
echo -n _${s}
;;
esac
done
}
catted="$(paramCat "$#")"
echo ${catted/_/}

Resources