I need to print the argument number of which user types in. No matter what I do I always get just an empty line
echo "Give argument number"
read number
allV=$#
echo ${allV[$number]}
what is wrong with this few lines? Even if I start the script with a few arguments and I just manually write sth like"
echo ${allV[1]}
again all I get is an empty line.
Bash lets you use an indirect reference, which works also on numbered parameters:
echo "${!number}"
It also lets you slice the argument list:
echo "${#:$number:1}"
Or you could copy the arguments into an array:
argv=("$#")
echo "${argv[number]}"
In all cases, the quotes are almost certainly required, in case the argument includes whitespace and/or glob characters.
To handle $# as an array, just change it to ("$#") :
echo "Give argument number"
read number
allV=("$#")
echo ${allV[$number-1]}
Related
I try to use automator for renaming multiple files
I got this far:
the first variable must be inside the Exiftool command line
in this case I selected 2 files, but that could be 1 or 100 files
how do I make this happen? is it possible to start from array key 1 instead of array key 0 for the filenames?
The standard way to do this is to store $1 in a variable, then use shift to remove it from the argument list, and then use "$#" to get all of the remaining arguments (i.e. the original "$2" "$3" "$4" ...) Something like this:
RenameTo="$1"
shift
echo "New name: $RenameTo"
echo "files:" "$#"
I'm not sure exactly what you're trying to to with exiftool, so I won't try to give that full command.
Note that the double-quotes aren't required in zsh, but they make this portable to POSIX-compliant shells. Also, echo isn't a very good way to see what a command would do, because it looses the distinction between spaces within an argument (e.g. spaces in the new name, or within a filename) and spaces between arguments (e.g. between the filenamess in a list of them).
Given the following script:
#!/bin/bash
asteriskFiles=("sip.conf" "extensions.conf")
for asteriskFile in $asteriskFiles
do
# backup current configuration file
cp somepath/${asteriskFile} test/
echo "test"
done
This gives me the output "test" only once, so the loop runs only once instead of two times (two entries in asteriskFiles array). What am I doing wrong? Thanks for any hint!
An illustration:
$ asteriskFiles=("sip.conf" "extensions.conf")
$ echo $asteriskFiles # is equivalent to echo ${asteriskFiles[0]}
sip.conf
$ echo "${asteriskFiles[#]}"
sip.conf extensions.conf
Note that the quotes are important. echo ${asteriskFiles[#]} might seem to work, but bash would wordsplit on whitespace if any of your files had whitespace in them.
Write the beginning of your loop like this
for asteriskFile in "${asteriskFiles[#]}"
The Probem
The asteriskFiles variable holds an array. If you dereference it like a scalar, you only get the first element of the array.
The Solution
You want to use the correct shell parameter expansion to access all the subscript elements. For example:
$ echo "${asteriskFiles[#]}"
sip.conf extensions.conf
The # subscript (when correctly quoted) will expand to the properly-tokenized elements of your array, which your for-loop will then be able to iterate over.
Can anyone help me with this code? bash doesn't recognize the $2 only the first $1 show an error: read: '2': it is not a valid identificator.
#!/bin/bash
read $#
a=$#
You cannot read into $#, or into the variable called 2 (which $# expands to).
Instead, to reassign $2, you need to use set to completely rewrite the full set of positional parameters:
set -- one two
...will set $2 to two, and $# to 2 (since two items were provided).
By contrast, if you simply wish to use the value for $2 passed on your script's command line, you don't need to (and shouldn't) use read at all.
By contrast, if you want to access the last command-line argument, you can use indirect expansion for that:
set -- one two last
last_arg=$# # sets last_arg=3
result=${!last_arg} # sets result=last
...or, if you want to overwrite the last command-line argument with a value read from stdin:
read new_last
set -- "${#:1:$(( $# - 1 ))}" "$new_last"
I am trying to extract the number of lines from a file, and then use it in a variable. However, it keeps passing the file name, not the number of lines. I read through this question, but the examples are not working.
for i in $BASE/$TEMPLATE_DIR-$i$PRUNING_METHOD/*.txt
do
NUM_LINES=$(wc -l < $i)
echo $NUM_LINES
UPLOAD_CMD="sh sshpass_setup_verification.sh $EXP_ID-$i$PRUNING_METHOD__$NUM_LINES__features";
echo "$UPLOAD_CMD"
break 1;
done
Prints:
15 #the correct number of lines
sh sshpass_setup_verification.sh di-60sec-max/TemplateUser1.txt #where TemplateUser1.txt is the name of the file
Should print:
15
sh sshpass_setup_verification.sh di-60sec-max__15__features
A summary of what people are telling you in the comments:
for i in "${BASE}/${TEMPLATE_DIR}-${i}${PRUNING_METHOD}"/*.txt
do
num_lines=$(wc -l < "$i")
echo "$num_lines"
upload_cmd="sh sshpass_setup_verification.sh ${EXP_ID}-${i}${PRUNING_METHOD}__${num_lines}__features"
echo "$upload_cmd"
break
done
The key thing here is using double quotes around your parameter expansions and curly braces to disambiguate in situations where characters such as _ could be interpreted as part of a variable name but shouldn't. I've added them in several places where they aren't strictly needed but they do no harm.
I've also changed your variable names to lowercase. This will help you one day when you decide to have a variable called PATH and suddenly all your commands stop working.
Is it possible to create a script that will prompt a user to enter a number that will then programmatically be used for the number of arguments in a function/method? For example:
echo "Enter Number of arguments: "
read numOfArguments
Once a number is entered, this will stand for the number of parameters in a function. So if I enter 5, there should be 5 expected parameters within that method once called:
sampleMethod(){
...Takes 5 Parameters and actual code is here
}
sampleMethod ActualArgumentsfromPrompt
If this is possible can someone provide an example of how this is done? I am doing this because I would like to create a script that will parse through a log file but I need to pull specific items from the log that are set up similar to this: (0010,0020). The information I need will not always be a fixed number of items so that's why I would like to generate a prompt for a number of arguments.
Bash functions don't "expect" any number of arguments -- as you can see from the syntax, there's no list of parameter variables after the function name. They process arguments the same way the main shell does, by accessing them as $1, $2, etc. If you need to know how many arguments were passed, you can use $#.
To loop through all arguments, the common idiom is to process $1, then use shift to shift the argument list down.
sampleMethod() {
if [ $# -ne $numOfArguments ]
then echo Wrong number of arguments -$numOfArguments expected, $# provided >&2
return
fi
while [ $# -gt 0 ]; do
arg=$1
echo "$arg"
shift
done
}