我写了以下代码来获得字符串的最后一个字符:
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
它列出当前文件夹中的文件。
按照 @perreal 的说法,引用变量很重要,但我在评论中找到了一个更简单的方法来回答这个问题,所以我读了五遍文章...
str='abcd/'
echo "${str: -1}"
=> /
如评论中所指出的那样,您也可以使用${str:0-1}
。
str='abcd*'
echo "${str:0-1}"
=> *
注意:${str: -1}
中的额外空格是必需的,否则如果str
为空或者为零时,${str:-1}
会将1
作为默认值。
${parameter:-word}
Use Default Values. If parameter is unset or null, the
expansion of word is substituted. Otherwise, the value of
parameter is substituted.
感谢所有参与以上讨论的人;我已经适当地在整个帖子中添加了“加1”!
这就是为什么您需要引用变量的原因之一:
echo "${str:$i:1}"
否则,bash会在输出之前扩展变量,而且在这种情况下进行globbing。最好引用脚本的参数(以防有匹配的文件名):sh lash_ch.sh 'abcde*'
请参阅Bash参考手册中的扩展顺序。文件名扩展之前会先扩展变量。
要获取最后一个字符,只需使用索引-1
,因为负数索引从字符串末尾开始计数:
echo "${str: -1}"
冒号 (:
) 后面的空格是必须要有的。
没有空格这个方法将无法生效。
"${1: -1}"
就足够了。 - chorobaecho "${str:$((${#str}-1)):1}"
。这样可以返回不同数量的尾随字符。在我的 bash v4.1.0(1) 中有效。 - SaxDaddy我知道这是一个非常老的主题,但没有人提到对我来说最干净的答案是什么:
echo -n $str | tail -c 1
注意-n
只是为了让echo命令不在结尾添加换行符。
到目前为止,每个答案都暗示问题中的“shell”一词等同于Bash。
以下是在标准Bourne shell中执行此操作的方法:
printf "%s" "$str" | tail -c 1
echo -n
可以避免在$str
包含特殊格式字符时出现问题。 - Conrad Meyerprintf“%s”“$str”| ...
来修复您的答案 :-). - Conrad Meyer另一种使用awk脚本的解决方案:
最后一个字符:
echo $str | awk '{print substr($0,length,1)}'
最后 5 个字符:
echo $str | awk '{print substr($0,length-5,5)}'
cat file | awk '{print substr($0,length,1)}'
谢谢! - xmar单行:
${str:${#str}-1:1}
现在:
echo "${str:${#str}-1:1}"
echo "${str: -1}"
就足够了(注意:
和-
之间的空格)。 - gniourf_gniourf$((...))
进行_算术扩展_更为合理。 - gniourf_gniourf尝试:
"${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
对于可移植性,你可以使用"${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
输出:
.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.
expr $str : '.*\(.\)'
或者
echo ${str: -1}
对于任何对纯POSIX方法感兴趣的人:
#!/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"
${std: -1}
中间有空格,如果没有空格就无法正常工作。我遇到这个问题后发现${std:~0}
也可以使用(带或不带空格)。不确定这是否是官方文档记录的行为,我还没有去查阅。 - Bart.sh
脚本中使用此解决方案无效。例如,declare LAST=$(echo "${str: -1}")
会导致出现令人讨厌的红色错误栏,指示从冒号开始的语法错误。 - krb686${str:0-1}
。 - ttt${str::-1}
是${str: -1}
的另一种语法形式。 - lucasvc