文字列を区切り文字で分割し、N 番目の要素を取得します。

文字列を区切り文字で分割し、N 番目の要素を取得します。

文字列があります:

one_two_three_four_five

上記の文字列から変A数値twoと変数B値に保存する必要がありますfour

私はkshを使用しています。

答え1

フィールド区切り文字としてcutwith を使用し、必要なフィールドを取得します。_

A="$(cut -d'_' -f2 <<<'one_two_three_four_five')"
B="$(cut -d'_' -f4 <<<'one_two_three_four_five')"

echoHere 文字列の代わりにパイプを使用することもできます。

A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)"
B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)"

例:

$ s='one_two_three_four_five'

$ A="$(cut -d'_' -f2 <<<"$s")"
$ echo "$A"
two

$ B="$(cut -d'_' -f4 <<<"$s")"
$ echo "$B"
four

に改行文字が含まれている場合、 の 2番目/4番目のフィールドではなく、の各行の2番目/4番目のフィールド$sを含む複数行の文字列が返されることに注意してください。$s$s

答え2

答えが知りたかったのでawk、ここに一つあります:

A=$(awk -F_ '{print $2}' <<< 'one_two_three_four_five')
B=$(awk -F_ '{print $4}' <<< 'one_two_three_four_five')  

オンラインでお試しください!

答え3

POSIX sh構文のみを使用すると、パラメータ置換構造一度に 1 つの区切り文字を解析します。このコードでは、必要な数のフィールドがあることを前提としています。そうでない場合は、最後のフィールドが繰り返されます。

string='one_two_three_four_five'
remainder="$string"
first="${remainder%%_*}"; remainder="${remainder#*_}"
second="${remainder%%_*}"; remainder="${remainder#*_}"
third="${remainder%%_*}"; remainder="${remainder#*_}"
fourth="${remainder%%_*}"; remainder="${remainder#*_}"

あるいは、引用符なしのパラメータ置換を次のように使用することもできます。ワイルドカード拡張障害者およびIFS区切り文字に設定(これは、区切り文字が単一の空白以外の文字である場合、または任意の空白シーケンスが区切り文字である場合にのみ機能します)。

string='one_two_three_four_five'
set -f; IFS='_'
set -- $string
second=$2; fourth=$4
set +f; unset IFS

これにより、位置パラメータが上書きされます。関数内でこれを行うと、関数の位置パラメータのみが影響を受けます。

改行文字を含まない文字列に対するもう 1 つのアプローチは、read組み込みを使用することです。

IFS=_ read -r first second third fourth trail <<'EOF'
one_two_three_four_five
EOF

答え4

を使用するとzsh、文字列 (on _) を配列に分割できます。

non_empty_elements=(${(s:_:)string})
all_elements=("${(@s:_:)string}")

そして、配列インデックスを介して各要素にアクセスします。

print -r -- ${all_elements[4]}

zsh(他のほとんどのシェルと同様ですが、ksh/とは異なりますbash配列のインデックスは1から始まります

または、直接 1 つの展開で:

print -r -- "${${(@s:_:)string}[4]}"

または、匿名関数を使用して、要素をその$1$2... で使用できるようにします。

(){print -r -- $4} "${(@s:_:)string}"

関連情報