如何获取shell中字符串的最后一个字符?

thi*_*er3 112 string bash shell

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

str=$1
i=$((${#str}-1))
echo ${str:$i:1}
Run Code Online (Sandbox Code Playgroud)

它适用于abcd/:

$ bash last_ch.sh abcd/
/
Run Code Online (Sandbox Code Playgroud)

不适用于abcd*:

$ bash last_ch.sh abcd*
array.sh assign.sh date.sh dict.sh full_path.sh last_ch.sh
Run Code Online (Sandbox Code Playgroud)

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

qui*_*tin 179

根据@perreal,引用变量很重要,但因为我在评论中找到一个更简单的方法来解决这个问题之前,我读过这篇文章5次...

str='abcd/'
echo "${str: -1}"
Run Code Online (Sandbox Code Playgroud)

输出: /

str='abcd*'
echo "${str: -1}"
Run Code Online (Sandbox Code Playgroud)

输出: *

感谢参与上述活动的所有人; 我已经在整个帖子中正确添加了+ 1!

  • 注意:注意`$ {std:-1}`里面的空格,没有这个空间就不行了.我遇到了这个,发现`$ {std:~0}`也有效(有或没有空格).不确定这是否是记录在案的行为,我没有费心去查找. (25认同)
  • 记录在案.man bash说:以 - 开头的算术表达式必须用前面的空格分隔:与使用默认值扩展区别开来 (4认同)
  • 这太棒了,谢谢你的分享.虽然BASH手册页几乎无法阅读,但我已多次在那里.我认为他们可以围绕shell脚本大学开设大学课程. (3认同)
  • 当尝试将检索到的字符分配给变量时,此解决方案在`.sh`脚本中不起作用.例如`declare LAST = $(echo"$ {str:-1}")`这将导致令人讨厌的红条显示从以下位置开始的语法错误: (3认同)
  • 如果编辑器语法检查不喜欢那个空间,请尝试`$ {str:0-1}` (2认同)

per*_*eal 69

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

echo "${str:$i:1}"
Run Code Online (Sandbox Code Playgroud)

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

sh lash_ch.sh 'abcde*'
Run Code Online (Sandbox Code Playgroud)

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

  • 顺便说一句,负指数从右计算,所以"$ {1:-1}"就足够了. (58认同)
  • @ choroba的回答:注意该死的空间!这总是让我兴奋:"$ {1:-1}`不起作用"! (13认同)
  • 您应该回复为正式的解决方案,而不是在评论中. (6认同)

小智 30

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

echo -n $str | tail -c 1
Run Code Online (Sandbox Code Playgroud)

请注意,-n回声最后不包括换行符.

  • 甚至不比$ {str:-1}更清洁 (12认同)
  • 它更干净,因为它不依赖于bash-ism,所以它适用于任何Posix shell. (7认同)

phe*_*hep 9

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

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

printf "%s" "$str" | tail -c 1
Run Code Online (Sandbox Code Playgroud)

  • 不完全是 bashism,但 POSIX 认识到它是实现定义的(“如果第一个操作数是 -n,或者如果任何操作数包含 <反斜杠> 字符,则结果是实现定义的”)。你的答案可以用 `printf "%s" "$str" | 来修正。...` :-)。 (4认同)
  • user5394399 提出的 `echo -n` 避免了 `$str` 包含特殊格式字符时的问题。 (2认同)
  • `-n` 开关是一种 bashism。它不能在标准 Bourne shell 中工作,如破折号等......这就是我的答案的重点。 (2认同)

mr.*_*123 6

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

最后 1 个字符:

echo $str | awk '{print substr($0,length,1)}'
Run Code Online (Sandbox Code Playgroud)

最后 5 个字符:

echo $str | awk '{print substr($0,length-5,5)}'
Run Code Online (Sandbox Code Playgroud)


Edu*_*omo 5

单线:

${str:${#str}-1:1}
Run Code Online (Sandbox Code Playgroud)

现在:

echo "${str:${#str}-1:1}"
Run Code Online (Sandbox Code Playgroud)


mar*_*ite 5

尝试:

"${str:$((${#str}-1)):1}"
Run Code Online (Sandbox Code Playgroud)

例如:

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
Run Code Online (Sandbox Code Playgroud)