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]}