154

我写了以下几行来获取字符串的最后一个字符:

str=$1
i=$((${#str}-1))
echo ${str:$i:1}

它适用于abcd/

$ bash last_ch.sh abcd/
/

不适用于abcd*

$ bash last_ch.sh abcd*
array.sh assign.sh date.sh dict.sh full_path.sh last_ch.sh

列出了当前文件夹中的文件

4

11 回答 11

209

根据@perreal,引用变量很重要,但因为我读了这篇文章 5 次,然后才在评论中找到解决手头问题的更简单方法......

str='abcd/'
echo "${str: -1}"

输出:/

str='abcd*'
echo "${str: -1}"

输出:*

感谢所有参与上述活动的人;我在整个线程中适当地添加了+1!

于 2014-02-07T19:02:59.000 回答
133

这就是您需要引用变量的原因之一:

echo "${str:$i:1}"

否则,bash 会扩展变量,在这种情况下会在打印输出之前进行通配。最好将参数引用到脚本中(如果您有匹配的文件名):

sh lash_ch.sh 'abcde*'

另请参阅bash 参考手册中的扩展顺序。变量在文件名扩展之前被扩展。

要获取最后一个字符,您应该将其-1用作索引,因为负索引从字符串末尾开始计数:

echo "${str: -1}"

冒号 ( :) 后的空格是必需的。

没有空间,这种方法将行不通。

于 2013-07-09T07:58:27.023 回答
46

我知道这是一个非常古老的线程,但没有人提到对我来说哪个是最干净的答案:

echo -n $str | tail -c 1

请注意,-n只是这样 echo 在末尾不包含换行符。

于 2015-09-30T17:52:43.110 回答
14

到目前为止,每个答案都暗示问题中的“shell”一词等同于 Bash。

这就是在标准 Bourne shell 中如何做到这一点:

printf "%s" "$str" | tail -c 1
于 2017-02-26T13:29:01.193 回答
5

使用 awk 脚本的另一个解决方案:

最后 1 个字符:

echo $str | awk '{print substr($0,length,1)}'

最后 5 个字符:

echo $str | awk '{print substr($0,length-5,5)}'
于 2015-07-16T09:20:16.503 回答
5

单线:

${str:${#str}-1:1}

现在:

echo "${str:${#str}-1:1}"
于 2015-09-14T17:01:05.413 回答
4

尝试:

"${str:$((${#str}-1)):1}"

例如:

someone@mypc:~$ str="A random string*"; echo "$str"
A random string*
someone@mypc:~$ echo "${str:$((${#str}-1)):1}"
*
someone@mypc:~$ echo "${str:$((${#str}-2)):1}"
g
于 2016-05-11T00:35:26.933 回答
1

For portability you can say "${s#"${s%?}"}":

#!/bin/sh
m=bzzzM n=bzzzN
for s in \
    'vv'  'w'   ''    'uu  ' ' uu ' '  uu' / \
    'ab?' 'a?b' '?ab' 'ab??' 'a??b' '??ab' / \
    'cd#' 'c#d' '#cd' 'cd##' 'c##d' '##cd' / \
    'ef%' 'e%f' '%ef' 'ef%%' 'e%%f' '%%ef' / \
    'gh*' 'g*h' '*gh' 'gh**' 'g**h' '**gh' / \
    'ij"' 'i"j' '"ij' "ij'"  "i'j"  "'ij"  / \
    'kl{' 'k{l' '{kl' 'kl{}' 'k{}l' '{}kl' / \
    'mn$' 'm$n' '$mn' 'mn$$' 'm$$n' '$$mn' /
do  case $s in
    (/) printf '\n' ;;
    (*) printf '.%s. ' "${s#"${s%?}"}" ;;
    esac
done

Output:

.v. .w. .. . . . . .u. 
.?. .b. .b. .?. .b. .b. 
.#. .d. .d. .#. .d. .d. 
.%. .f. .f. .%. .f. .f. 
.*. .h. .h. .*. .h. .h. 
.". .j. .j. .'. .j. .j. 
.{. .l. .l. .}. .l. .l. 
.$. .n. .n. .$. .n. .n. 
于 2020-10-30T23:22:25.173 回答
0
expr "$str" : '.*\(.\)'

或者

echo "${str: -1}"

6chars4so

于 2020-10-30T16:23:43.437 回答
0

For anyone interested in a pure POSIX method:

https://github.com/spiralofhope/shell-random/blob/master/live/sh/scripts/string-fetch-last-character.sh

#!/usr/bin/env  sh

string_fetch_last_character() {
  length_of_string=${#string}
  last_character="$string"
  i=1
  until [ $i -eq "$length_of_string" ]; do
    last_character="${last_character#?}"
    i=$(( i + 1 ))
  done

  printf  '%s'  "$last_character"
}


string_fetch_last_character  "$string"
于 2021-01-05T22:51:34.683 回答
-3
echo $str | cut -c $((${#str}))

是个好办法

于 2015-04-11T07:18:58.550 回答