Q:

Split string by delimiter and get N-th element

I have a string:
one_two_three_four_five

I need to save in a variable A value two and in variable B value fourfrom the above string
I am using ksh.

A:

Use cut with _ as the field delimiter and get desired fields:
A="$(cut -d'_' -f2 <<<'one_two_three_four_five')"
B="$(cut -d'_' -f4 <<<'one_two_three_four_five')"

You can also use echo and pipe instead of Here string:
A="$(echo 'one_two_three_four_five' | cut -d'_' -f2)"
B="$(echo 'one_two_three_four_five' | cut -d'_' -f4)"

Example:
$ s='one_two_three_four_five'

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

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

Beware that if $s contains newline characters, that will return a multiline string that contains the 2nd/4th field in each line of $s, not the 2nd/4th field in $s.

A:

Using only POSIX sh constructs, you can use parameter substitution constructs to parse one delimiter at a time. Note that this code assumes that there is the requisite number of fields, otherwise the last field is repeated.
string='one_two_three_four_five'
remainder="$string"
first="${remainder%%_*}"; remainder="${remainder#*_}"
second="${remainder%%_*}"; remainder="${remainder#*_}"
third="${remainder%%_*}"; remainder="${remainder#*_}"
fourth="${remainder%%_*}"; remainder="${remainder#*_}"

Alternatively, you can use an unquoted parameter substitution with wildcard expansion disabled and IFS set to the delimiter character (this only works if the delimiter is a single non-whitespace character or if any whitespace sequence is a delimiter).
string='one_two_three_four_five'
set -f; IFS='_'
set -- $string
second=$2; fourth=$4
set +f; unset IFS

This clobbers the positional parameters. If you do this in a function, only the function's positional parameters are affected.
Yet another approach for strings that don't contain newline characters is to use the read builtin.
IFS=_ read -r first second third fourth trail <<'EOF'
one_two_three_four_five
EOF

A:

Wanted to see an awk answer, so here's one:
A=$(awk -F_ '{print $2}' <<< 'one_two_three_four_five')
B=$(awk -F_ '{print $4}' <<< 'one_two_three_four_five')

