如何在shell中分割字符串并获取最后一个字段?

时间:2022-09-25 15:47:19

Suppose I have the string 1:2:3:4:5 and I want to get its last field (5 in this case). How do I do that using Bash? I tried cut, but I don't know how to specify the last field with -f.

假设我有一个字符串1:2:3:4:5,我想要得到它的最后一个字段(在这个例子中是5)。如何使用Bash?我试过了,但我不知道如何用-f来指定最后一个场。

14 个解决方案

#1


293  

You can use string operators:

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

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

This trims everything from the front until a ':', greedily.

从前面一直到“:”,这都是很贪婪的。

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

#2


269  

Another way is to reverse before and after cut:

另一种方法是在切割前后反转:

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

This makes it very easy to get the last but one field, or any range of fields numbered from the end.

这使得我们很容易获得最后一个字段,或者从末尾编号的任何字段。

#3


57  

It's difficult to get the last field using cut, but here's (one set of) solutions in awk and perl

使用cut来获取最后一个字段是很困难的,但是这里有awk和perl中的(一组)解决方案。

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

#4


19  

Assuming fairly simple usage (no escaping of the delimiter, for example), you can use grep:

假设相当简单的用法(例如,不能转义分隔符),可以使用grep:

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

Breakdown - find all the characters not the delimiter ([^:]) at the end of the line ($). -o only prints the matching part.

分解,发现所有的人物不是分隔符([^:])的末尾($)。-o只打印匹配部分。

#5


16  

One way:

一个方法:

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

Another, using an array:

另一个使用一个数组:

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

Yet another with an array:

还有一个数组:

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

Using Bash (version >= 3.2) regular expressions:

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

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

#6


5  

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

Simply translate the delimiter into a newline and choose the last entry with tail -1.

简单地将分隔符转换为换行符,并选择尾部-1的最后一个条目。

#7


4  

Using sed:

使用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

#8


4  

If your last field is a single character, you could do this:

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

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

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

Check string manipulation in bash.

在bash中检查字符串操作。

#9


3  

Using Bash.

使用Bash。

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

#10


2  

There are many good answers here, but still I want to share this one using basename :

这里有很多不错的答案,但我还是想用basename来分享这个:

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

However it will fail if there are already some '/' in your string. If slash / is your delimiter so you just have to (and should) use basename.

但是,如果字符串中已经有一些“/”,它就会失败。如果斜杠/是您的分隔符,那么您只需要(并且应该)使用basename。

It's not the best answer but it just shows how you can be creative using bash commands.

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

#11


2  

echo "a:b:c:d:e"|xargs -d : -n1|tail -1

First use xargs split it using ":",-n1 means every line only have one part.Then,pring the last part.

首先使用xargs将其拆分为“:”,-n1表示每一行只有一个部分。然后,印刷面积最后一部分。

#12


1  

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

#13


1  

For those that comfortable with Python, https://github.com/Russell91/pythonpy is a nice choice to solve this problem.

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

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

From the pythonpy help: -x treat each row of stdin as x.

从pythonpy帮助:-x将每一行stdin视为x。

With that tool, it is easy to write python code that gets applied to the input.

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

#14


0  

a solution using the read builtin

使用read builtin的解决方案。

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

#1


293  

You can use string operators:

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

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

This trims everything from the front until a ':', greedily.

从前面一直到“:”,这都是很贪婪的。

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

#2


269  

Another way is to reverse before and after cut:

另一种方法是在切割前后反转:

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

This makes it very easy to get the last but one field, or any range of fields numbered from the end.

这使得我们很容易获得最后一个字段,或者从末尾编号的任何字段。

#3


57  

It's difficult to get the last field using cut, but here's (one set of) solutions in awk and perl

使用cut来获取最后一个字段是很困难的,但是这里有awk和perl中的(一组)解决方案。

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

#4


19  

Assuming fairly simple usage (no escaping of the delimiter, for example), you can use grep:

假设相当简单的用法(例如,不能转义分隔符),可以使用grep:

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

Breakdown - find all the characters not the delimiter ([^:]) at the end of the line ($). -o only prints the matching part.

分解,发现所有的人物不是分隔符([^:])的末尾($)。-o只打印匹配部分。

#5


16  

One way:

一个方法:

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

Another, using an array:

另一个使用一个数组:

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

Yet another with an array:

还有一个数组:

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

Using Bash (version >= 3.2) regular expressions:

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

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

#6


5  

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

Simply translate the delimiter into a newline and choose the last entry with tail -1.

简单地将分隔符转换为换行符,并选择尾部-1的最后一个条目。

#7


4  

Using sed:

使用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

#8


4  

If your last field is a single character, you could do this:

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

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

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

Check string manipulation in bash.

在bash中检查字符串操作。

#9


3  

Using Bash.

使用Bash。

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

#10


2  

There are many good answers here, but still I want to share this one using basename :

这里有很多不错的答案,但我还是想用basename来分享这个:

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

However it will fail if there are already some '/' in your string. If slash / is your delimiter so you just have to (and should) use basename.

但是,如果字符串中已经有一些“/”,它就会失败。如果斜杠/是您的分隔符,那么您只需要(并且应该)使用basename。

It's not the best answer but it just shows how you can be creative using bash commands.

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

#11


2  

echo "a:b:c:d:e"|xargs -d : -n1|tail -1

First use xargs split it using ":",-n1 means every line only have one part.Then,pring the last part.

首先使用xargs将其拆分为“:”,-n1表示每一行只有一个部分。然后,印刷面积最后一部分。

#12


1  

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

#13


1  

For those that comfortable with Python, https://github.com/Russell91/pythonpy is a nice choice to solve this problem.

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

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

From the pythonpy help: -x treat each row of stdin as x.

从pythonpy帮助:-x将每一行stdin视为x。

With that tool, it is easy to write python code that gets applied to the input.

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

#14


0  

a solution using the read builtin

使用read builtin的解决方案。

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