109

I have a Bash variable, $word, which is sometimes a word or sentence, e.g.:

word="tiger"

Or:

word="This is a sentence."

How can I make a new Bash variable which is equal to only the first letter found in the variable? E.g., the above would be:

echo $firstletter
t

Or:

echo $firstletter
T
Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
Village
  • 22,513
  • 46
  • 122
  • 163

7 Answers7

346
word="tiger"
firstletter=${word:0:1}
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
93
word=something
first=${word::1}
Adam Liss
  • 47,594
  • 12
  • 108
  • 150
  • 1
    This would be wonderful, but does not work for me, neither in bash 4.3.11 nor in zsh 5.0.5 – yoniLavi Mar 29 '16 at 16:59
  • 1
    With GNU bash v4.3.11, `first` is set to the letter `s`. You can see it with `echo $s`. If that doesn't work for you, and you'd like help debugging, please copy and paste the command(s) you typed and their output. – Adam Liss Mar 30 '16 at 18:54
  • 2
    Thanks Adam, my bad, I can't figure out why it didn't work for me before, but it works perfectly fine now on several version of bash I tried, going back to GNU bash, v3.1.0. Still doesn't work in zsh, but the question is tagged "bash", so that's irrelevant. – yoniLavi Mar 31 '16 at 01:37
  • Thanks for following up and confirming! Glad it's working for you. – Adam Liss Apr 01 '16 at 13:00
  • 1
    For zsh users: It is working with `${word:0:1}` – luator Jun 10 '21 at 12:07
45
initial="$(echo $word | head -c 1)"

Every time you say "first" in your problem description, head is a likely solution.

thiton
  • 35,651
  • 4
  • 70
  • 100
  • 8
    Please note that there is no `-c` option in POSIX head: . – gioele Jan 09 '15 at 10:02
  • 12
    This does return the first letter, but it's an overkill, and the solution depends on external utilities (head). This can be done in pure shell, which is cleaner. – automaciej Oct 07 '16 at 09:51
  • 30
    This should not be the accepted answer, for the reasons pointed out by the above comments. The real answers are below - `${word:0:1}` or `${word::1}`. – noamtm Dec 08 '16 at 07:37
  • 1
    For POSIX compliance you could do `echo "$word" | fold -w1 | head -n 1`, `printf '%.1s' "$X"` or `printf '%c' "$X"` but these are all subject to single v. multi byte character shenanigans. – phicr Mar 01 '17 at 16:08
  • Wait, so is `head -c n`, whoops. `echo "fábio" | head -c 2` gives `f� `, so that's another problem with this I guess. – phicr Mar 01 '17 at 16:28
  • 1
    To update the accepted answer would take a @Villiage. Wanna? The community would thank you ... – erik258 Dec 28 '19 at 02:34
  • This is overkill if you want to get the first character(s) of a bash variable. It is a fine solution if you want the first character(s) of anything else regardless of your shell. E.g. in a script run by `sh`: `date +%N | head -c 7`. – YSC Oct 08 '20 at 14:54
17

A portable way to do it is to use parameter expansion (which is a POSIX feature):

$ word='tiger'
$ echo "${word%"${word#?}"}"
t
Mateusz Piotrowski
  • 8,029
  • 10
  • 53
  • 79
  • More reasonable to use are the other answers with `::` but I can't miss to upvote such an abuse of expansion. Nicely done. – akostadinov May 19 '21 at 21:14
  • It's *often* the case that you need to shell out in a scripting environment that mandates, well POSIX `sh`, not `bash` (though that was not part of the question) – usretc Sep 07 '21 at 19:57
7

With cut :

word='tiger'
echo "${word}" | cut -c 1
Franckyz
  • 71
  • 1
  • 1
2

Since you have a sed tag here is a sed answer:

echo "$word" | sed -e "{ s/^\(.\).*/\1/ ; q }"

Play by play for those who enjoy those (I do!):

{

  • s: start a substitution routine
    • /: Start specifying what is to be substituted
    • ^\(.\): capture the first character in Group 1
    • .*:, make sure the rest of the line will be in the substitution
    • /: start specifying the replacement
    • \1: insert Group 1
    • /: The rest is discarded;
  • q: Quit sed so it won't repeat this block for other lines if there are any.

}

Well that was fun! :) You can also use grep and etc but if you're in bash the ${x:0:1} magick is still the better solution imo. (I spent like an hour trying to use POSIX variable expansion to do that but couldn't :( )

phicr
  • 1,332
  • 9
  • 16
1

Using bash 4:

x="test"
read -N 1 var <<< "${x}"
echo "${var}"
leogtzr
  • 480
  • 4
  • 7