1:2:3:4:5
という文字列があり、その最後のフィールド(この場合は5
)を取得したいとします。 Bashを使ってそれを行うにはどうすればいいですか?私はcut
を試しましたが、-f
で最後のフィールドを指定する方法がわかりません。
あなたは 文字列演算子 を使うことができます。
$ foo=1:2:3:4:5
$ echo ${foo##*:}
5
これは、前から ':'まですべてを貪欲に整えます。
${foo <-- from variable foo
## <-- greedy front trim
* <-- matches anything
: <-- until the last ':'
}
別の方法はcut
の前後で逆にすることです:
$ echo ab:cd:ef | rev | cut -d: -f1 | rev
ef
これにより、最後の1つのフィールド、または最後から番号が付けられた任意の範囲のフィールドを取得することが非常に簡単になります。
Cutを使って最後のフィールドを取得するのは困難ですが、これがawkとPerlの(1セットの)解決策です。
$ echo 1:2:3:4:5 | awk -F: '{print $ NF}' 5 $ echo 1:2:3:4:5 | Perl -F:-wane 'print $ F [-1]' 5
かなり単純な使い方(例えば、区切り文字をエスケープしない)を想定して、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(version> = 3.2)正規表現を使う:
var1="1:2:3:4:5"
[[ $var1 =~ :([^:]*)$ ]]
var2=${BASH_REMATCH[1]}
$ echo "a b c d e" | tr ' ' '\n' | tail -1
e
単に区切り文字を改行に変換して、最後のエントリをtail -1
で選択するだけです。
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
ここにはたくさんの良い答えがありますが、それでもbasenameを使ってこれを共有したいと思います。
basename $(echo "a:b:c:d:e" | tr ':' '/')
ただし、文字列にすでに「/」が含まれていると失敗します。スラッシュ/があなたの区切り文字であるならば、あなたはただbasenameを使わなければなりません(そしてそうすべきです)。
これは最良の答えではありませんが、bashコマンドを使用してクリエイティブになる方法を示しているだけです。
Bashを使う.
$ var1="1:2:3:4:0"
$ IFS=":"
$ set -- $var1
$ eval echo \$${#}
0
echo "a:b:c:d:e"|xargs -d : -n1|tail -1
最初の使用xargsは ":"を使って分割します - n1はすべての行が1つの部分だけを持つことを意味します。そして最後の部分をpringします。
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コードを書くのは簡単です。
Readビルトインを使用した解決策:
IFS=':' read -a fields <<< "1:2:3:4:5"
echo "${fields[4]}"
または、より一般的にするには
echo "${fields[-1]}" # prints the last item
for x in `echo $str | tr ";" "\n"`; do echo $x; done
sed
での正規表現のマッチングは貪欲です(常に最後に現れるものに行きます)。ここであなたが有利に使うことができます:
$ foo=1:2:3:4:5
$ echo ${foo} | sed "s/.*://"
5
あなたがpythonが好きでパッケージをインストールするオプションがあるなら、あなたは このpythonユーティリティ を使うことができます。
# install pythonp
pythonp -m pip install pythonp
echo "1:2:3:4:5" | pythonp "l.split(':')[-1]"
5
簡単な解決策は入力文字列の順序を逆にすることですが、答えが少し遅くなるかもしれません。これにより、長さに関係なく常に最後のアイテムを獲得できます。
[chris@desktop bin]$ echo 1:2:3:4:5 | rev | cut -d: -f1
5
ただし、この方法を使用していて、数字が1桁よりも大きい(またはどのような状況でも1文字よりも大きい)場合は、パイプ出力に対して別の 'rev'コマンドを実行する必要があります。
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1
42
[chris@desktop bin]$ echo 1:2:3:4:5:8:24 | rev | cut -d: -f1 | rev
24
応援できたらと嬉しい