For example, with the string a_link_list_java, use the _ character to separate the string in half would result in: a_link_list and java.

list_java would result in: list and java.

I want to take these two parts and store them into two variables.

I tried the cut command but it only works for only one character shown in the string

How can I accomplish this in a bash shell script?

3 Answers 3


The shell's parameter expansions can do that:

$ v="a_link_list_java"
$ printf "%s\n" "${v%_*}" "${v##*_}"

Though note that if the patterns in the expansion don't match, nothing is removed. So a value without an underscore would be unchanged by both transformations:

$ v=foo
$ printf "%s\n" "${v%_*}" "${v##*_}"

With sed:

var1=$(sed 's/_[^_]*$//' file)
var2=$(sed 's/.*_//' file)

Notice that sed is very greedy, so in the second case glob * swallows all characters, including previous underscores _.


$ echo "$var1"
$ echo "$var2"

Using awk you can have all in separate defining delimiter as _

VAR1=$(awk -F'_' '{print $1}' infile.txt) 

You can print which fields you want based on its index above instead of $1 that points to first field.

Or you can use bash and read as an array.

IFS='_' read -r -a array <<< "$myString"

then simply read with individual index number:

echo "${array[2]}"

Or even simply you can use bash parameter expansion:

VAR1="${myString%_*}"   # will gives you 'a_link_list' 
VAR2="${myString##*_}"  # will gives you 'java' 
VAR3="${VAR1%_*}"       # will gives you 'a_link' 
  • for example a_link_list_java , i want my first field to be a_link_list , not a, Because I do not know about how many '_' would contain in the string
    – Xing Peng
    Aug 3, 2017 at 19:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .