如何分裂一个字符串在壳和得到最后一个字段

假设我有一个字符串1:2:3:4:5,我想获取它的最后一个字段(在本例中是5)。我如何使用Bash做到这一点?我尝试了cut,但我不知道如何用-f指定最后一个字段。

479355 次浏览

假设使用相当简单(例如,没有转义分隔符),您可以使用grep:

$ echo "1:2:3:4:5" | grep -oE "[^:]+$"
5

分解-找到行($)末尾的所有字符,而不是分隔符([^:])。-o只打印匹配的部分。

一个方法:

var1="1:2:3:4:5"
var2=${var1##*:}

另一个,使用数组:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
var2=${var2[@]: -1}

还有一个数组:

var1="1:2:3:4:5"
saveIFS=$IFS
IFS=":"
var2=($var1)
IFS=$saveIFS
count=${#var2[@]}
var2=${var2[$count-1]}

使用Bash(版本>= 3.2)正则表达式:

var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}

你可以使用字符串运算符:

$ foo=1:2:3:4:5
$ echo ${foo##*:}
5

这将从前面到':'贪婪地修剪所有内容。

${foo  <-- from variable foo
##   <-- greedy front trim
*    <-- matches anything
:    <-- until the last ':'
}

使用Bash。

$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo  \$${#}
0

使用cut很难得到最后一个字段,但是这里有一些在awk和perl中的解决方案

echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'

另一种方法是在cut之前和之后反转:

$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef

这使得获取倒数第二个字段或从末尾开始编号的任何字段范围非常容易。

for x in `echo $str | tr ";" "\n"`; do echo $x; done

如果你的最后一个字段是一个字符,你可以这样做:

a="1:2:3:4:5"


echo ${a: -1}
echo ${a:(-1)}

检查bash中的字符串操作

$ echo "a b c d e" | tr ' ' '\n' | tail -1
e

只需将分隔符转换为换行符,并选择带有tail -1的最后一项。

这里有很多很好的答案,但我仍然想用basename来分享这个答案:

 basename $(echo "a:b:c:d:e" | tr ':' '/')

然而它会失败,如果已经有一些'/'在你的字符串。 如果斜杠/是你的分隔符,那么你就必须(也应该)使用basename。< / p >

这不是最好的答案,但它只是展示了如何创造性地使用bash命令。

使用sed:

$ echo '1:2:3:4:5' | sed 's/.*://' # => 5


$ echo '' | sed 's/.*://' # => (empty)


$ echo ':' | sed 's/.*://' # => (empty)
$ echo ':b' | sed 's/.*://' # => b
$ echo '::c' | sed 's/.*://' # => c


$ echo 'a' | sed 's/.*://' # => a
$ echo 'a:' | sed 's/.*://' # => (empty)
$ echo 'a:b' | sed 's/.*://' # => b
$ echo 'a::c' | sed 's/.*://' # => c
echo "a:b:c:d:e"|xargs -d : -n1|tail -1

首先使用xargs使用“:”分割它,-n1意味着每一行只有一个部分。然后,弹簧最后一部分。

使用read内置的解决方案:

IFS=':' read -a fields <<< "1:2:3:4:5"
echo "${fields[4]}"

或者,让它更通用:

echo "${fields[-1]}" # prints the last item

对于那些熟悉Python的人来说,https://github.com/Russell91/pythonpy是解决这个问题的一个不错的选择。

$ echo "a:b:c:d:e" | py -x 'x.split(":")[-1]'

来自python帮助:-x treat each row of stdin as x

使用该工具,可以很容易地编写应用于输入的python代码。

编辑 (Dec 2020): Pythonpy不再在线。 这里有一个替代方案:

$ echo "a:b:c:d:e" | python -c 'import sys; sys.stdout.write(sys.stdin.read().split(":")[-1])'

它包含更多的样板代码(即sys.stdout.read/write),但只需要来自python的std库。

如果你喜欢python并且有安装包的选项,你可以使用这个python实用程序

# install pythonp
pythonp -m pip install pythonp


echo "1:2:3:4:5" | pythonp "l.split(':')[-1]"
5

sed中的正则表达式匹配是贪婪的(总是到最后一个位置),你可以在这里使用它:

$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5

如果你想使用cut,你可以尝试这样做:

echo "1:2:3:4:5" | cut -d ":" -f5

你也可以像这样使用grep try:

echo " 1:2:3:4:5" | grep -o '[^:]*$'

抱歉,我不能评论,但这里; 从@mateusz-piotrowski @user3133260回答,

Echo“a:b:c:d::e::::”;| tr ':' ' ' | xargs | tr ' ' '\n' | tail -1

首先,tr ':' ' ' ->将':'替换为空格

然后,用xargs修整

在那之后,tr ' ' '\n' ->将剩余空白替换为换行符

最后,tail -1 ->获取最后一个字符串