2

How do I get the first digit from a number? For example, 25 - to get only the "2" from the 25.

This is what I tried:

echo -n "Enter age: "    
read age    
echo $(s:0:1)
4
  • 2
    What was your result? What is s supposed to be in the third line? Apr 26, 2020 at 18:51
  • it doesn't work. it display the entire "s:0:1" Apr 26, 2020 at 18:54
  • 2
    It should be a parameter expansion ${s:0:1}, not a command substitution $(s:0:1) (which should give you a command-not-found error, not the literal string s:0:1).
    – chepner
    Apr 27, 2020 at 12:47
  • @DavidLloyd The script you posted wouldn't produce that output (it would report an error), you must have copied it wrong. Can you edit the question to show what you really executed?
    – Barmar
    Apr 27, 2020 at 15:25

4 Answers 4

22

You're using the wrong variable s instead of age and parameter expansion works with curly braces ${...}:

read -p "Enter age: " age
echo "${age:0:1}"
2
  • This should resolve the issues in the original script
    – Matt Minga
    Apr 27, 2020 at 18:43
  • As long as the number doesn't have a sign !
    – user232326
    Apr 28, 2020 at 18:19
6

The most basic and POSIX compatible way (assuming no sign) is:

echo "${age%"${age#?}"}"

In some shells (bash,ksh,zsh):

echo "${age:0:1}"

If the value could contain a sign, remove it first:

$ age=+23
$ age=${age#[+-]}
$ echo "${age%"${age#?}"}"
2
9
  • See also printf '%s\n' "${age[1]}" in zsh or yash (or printf '%s\n' $age[1] in zsh). Beware echo - outputs an empty line in zsh (as - is the end of option delimiter) Apr 28, 2020 at 11:29
  • It may be possible to deal with a leading - by using echo -- instead; many commands accept -- as a delimiter to mean "what follows are positional arguments, not options"... but it will depend on what echo is being used. (Note that echo is often a shell built-in.)
    – Matthew
    Apr 28, 2020 at 14:18
  • No @Matthew there is no echo (builtin or external) that takes -- as meaning "end of options", none. All will just output a --. Try it.
    – user232326
    Apr 28, 2020 at 18:10
  • @StéphaneChazelas (1) Both ${age[1]} and $age[1] are zshisms, only work inside zsh and are not portable. Why use a "limited to one particular shell" syntax when a more portable solution also exist ?. (2) There is no issue with echo - as the - either doesn't exist (no sign) or, if it exists, it is removed with age=${age#[+-]}. Read the answer.
    – user232326
    Apr 28, 2020 at 18:18
  • ${a[1]} is zsh or yash like I said. Those are additional notes to complement your answer (which already mentions ksh93isms), it's not a critic to your answer. echo ${a:0:1} will output an empty line if $a is -1, it's still worth noting. Apr 28, 2020 at 18:23
2

As you mention bash in the title:

#!/bin/bash

read -p 'Enter a number: '
printf '%.1s\n' "$REPLY"

This prints only the first character of the string $REPLY (read by read).

To store this in another variable, othervar, use

printf -v othervar '%.1s' "$REPLY"

You could also just use a simple variable substitution, as mentioned by others,

printf '%s\n' "${REPLY:0:1}"

where 0 is the zero-based position in the string where we want to start pulling out data, and 1 is the length of the substring that we want.

You can assign ${REPLY:0:1} to another variable directly:

othervar=${REPLY:0:1}
1

POSIX compatible solution:

#!/usr/bin/env sh

printf "Enter age: "
read -r age
echo "$age"  
echo first digit: "$(echo "$age" | cut -c1)"

Example:

$ ./script.sh
Enter age: 25
25
first digit: 2
3
  • Thanks very much Apr 26, 2020 at 19:00
  • @DavidLloyd If one of the answers solved your issue, please take a moment to accept it by clicking on the checkmark on the left. That will mark the question as answered and is the way that thanks are conveyed on the Stack Exchange sites.
    – terdon
    Apr 26, 2020 at 19:05
  • A much slower solution than "${age:0:1}".
    – user232326
    Apr 28, 2020 at 18:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.