5

Let's say the variable numbers=$@ where $@is from user input. The user typed in ./script.sh 901.32.02 and I want to get the first digit 9 and store in another variable. How can I do this? I was told to do

  for n in `seq 1 $count`
    do var=${numbers[0]}
  done

but that prints out the whole input if I echo $var instead of just 9.

Ned64
  • 8,726
Rashad
  • 141

5 Answers5

13

In Bash, you can extract the first character using parameter expansion:

${parameter:offset:length}

Example:

$ var=901.32.02
$ first_char="${var:0:1}"
$ echo "${first_char}"
9
nxnev
  • 3,654
  • @Kusalananda Oh, sorry, when I saw your answer it had a different expansion ("${numbers%%.*}") which gives a different output (901). – nxnev Apr 02 '18 at 08:19
  • Ah, yes, because I interpreted "number" as "number" rather than "digit" before I saw my error. Ah well, I'll remove that comment anyway as you added the generic form of the expansion too. – Kusalananda Apr 02 '18 at 08:21
5
numbers='901.32.02'
firstdigit="${numbers:0:1}"

printf 'The first digit is "%s"\n' "$firstdigit"

The result of the above is

The first digit is "9"

The ${numbers:0:1} parameter expansion in bash give you the substring of length 1 from the start of the string (offset zero). This is a bash-specific parameter substitution (also in some other shells, but not in the POSIX standard).

In a POSIX shell, you may also do

firstdigit=$( printf "%s\n" "$numbers" | cut -c 1 )

This will use cut to only return the first character.

Or, using standard parameter expansions,

firstdigit="${numbers%${numbers#?}}"

This first uses ${numbers#?} to create a string with the first digit removed, then it removes that string from the end of $numbers using ${numbers%suffix} (where suffix is the result of the first expansion).


The above assumes that the first character of $numbers is actually a digit. If it is not, then you would have to first remove non-digits from the start of the value:

numbers=$( printf '%s\n' "$numbers" | sed 's/^[^0-9]*//' )

or,

numbers="${numbers#${numbers%%[0-9]*}}"

${numbers[0]} would have worked if each character was a separate element in the array numbers (and if the first character was a digit). Since numbers is not an array, it's equivalent to just $numbers.

Kusalananda
  • 333,661
3

You can use below method too

cat script.sh

   #!/bin/bash
echo $1 | awk '{print substr($1,1,1)}'



 sh script.sh 90

Where 90 is the user input

output is 9

  • so the above code is correct? it's not working for me though, im using a bash script – Rashad Apr 02 '18 at 04:44
  • @Rashad Yes, you can easily call the external program awk from your bash script and store the results in a bash script variable! – Ned64 Apr 02 '18 at 08:16
  • Note also that the #!-line must not be preceded by blank lines or spaces. You are also specifying bash as the script language in the script itself, while running it with sh. – Kusalananda Apr 02 '18 at 08:16
2

With colrm

echo '901.32.02' | colrm 2
ctac_
  • 1,960
1

If you want to detect only digits (not other character types) you should use a simple regular expression.

[[ ${numbers} =~ ^([[:digit:]]) ]] && var=${BASH_REMATCH[1]}

In $var is a digit or it is empty (even not declared).

Marco
  • 461