340

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.

4

17 に答える 17

506

文字列演算子を使用できます:

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

これにより、前面から「:」まですべてが貪欲にトリミングされます。

${foo  <-- from variable foo
  ##   <-- greedy front trim
  *    <-- matches anything
  :    <-- until the last ':'
 }
于 2010-07-02T00:05:40.870 に答える
378

別の方法は、前後を逆にすることですcut

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

これにより、最後の1つのフィールド、または最後から番号が付けられた任意の範囲のフィールドを非常に簡単に取得できます。

于 2012-02-03T08:39:53.820 に答える
91

カットを使用して最後のフィールドを取得することは困難ですが、ここにawkとperlのいくつかの解決策があります

echo 1:2:3:4:5 | awk -F: '{print $NF}'
echo 1:2:3:4:5 | perl -F: -wane 'print $F[-1]'
于 2010-07-02T07:09:21.627 に答える
35

かなり単純な使用法(たとえば、区切り文字のエスケープなし)を想定すると、grepを使用できます。

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

内訳-行末($)の区切り文字([^:])以外のすべての文字を検索します。-oは一致する部分のみを印刷します。

于 2010-07-01T23:39:25.163 に答える
19

一方通行:

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

もう1つは、配列を使用します。

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]}
于 2010-07-02T00:05:22.683 に答える
18

あなたが使用したい場合は、このようなものを試すことができますcut

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

次のように試してみることもできますgrep

echo " 1:2:3:4:5" | grep -o '[^:]*$'
于 2021-02-06T09:40:57.407 に答える
13
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e

区切り文字を改行に変換し、最後のエントリを。で選択するだけtail -1です。

于 2013-12-24T19:04:53.447 に答える
7

使用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
于 2016-11-10T10:09:35.020 に答える
3

最後のフィールドが単一の文字である場合、これを行うことができます。

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

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

bashで文字列の操作を確認してください。

于 2013-11-13T16:10:40.563 に答える
3

ここには多くの良い答えがありますが、それでも私はbasenameを使用してこれを共有したいと思います:

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

ただし、文字列にすでに「/」が含まれている場合は失敗します。スラッシュ/が区切り文字である場合は、basenameを使用する必要があります(使用する必要があります)。

これは最良の答えではありませんが、bashコマンドを使用して創造性を発揮する方法を示しています。

于 2016-04-26T11:33:56.537 に答える
2

Bashを使用します。

$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo  \$${#}
0
于 2010-07-02T01:16:16.097 に答える
1
echo "a:b:c:d:e"|xargs -d : -n1|tail -1

最初にxargsを使用して、「:」を使用して分割します。-n1は、すべての行に1つの部分しかないことを意味します。次に、最後の部分をpringします。

于 2016-12-07T06:51:26.193 に答える
1

組み込みの読み取りを使用したソリューション:

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

または、より一般的にするには:

echo "${fields[-1]}" # prints the last item
于 2017-11-24T19:27:11.330 に答える
0
for x in `echo $str | tr ";" "\n"`; do echo $x; done
于 2012-06-22T02:55:00.757 に答える
0

Pythonに慣れている人にとっては、https://github.com/Russell91/pythonpyがこの問題を解決するための良い選択です。

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

pythonpyヘルプから:-x treat each row of stdin as x

このツールを使用すると、入力に適用されるPythonコードを簡単に記述できます。

編集(2020年12月):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ライブラリのみが必要です。

于 2018-02-19T15:50:21.517 に答える
0

での正規表現の一致sedは貪欲であり(常に最後の発生になります)、ここで有利に使用できます。

$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5
于 2019-01-29T15:12:35.887 に答える
-1

Pythonが好きで、パッケージをインストールするオプションがある場合は、このpythonユーティリティを使用できます。

# install pythonp
pythonp -m pip install pythonp

echo "1:2:3:4:5" | pythonp "l.split(':')[-1]"
5
于 2019-01-05T18:04:19.853 に答える