BASH: Split a string without ‘cut’ or ‘awk’
Posted by AntonApr 10
For a little test script I’m writing I needed to split a line on a ‘;’ but preservere the “s and ‘s, something that echo doesn’t like to do. Digging deeper into the bash docs I see that there are some handy string handling functions.
#!/bin/bash
line=’this “is” a command;this “is” a pattern’
COMMAND=${line%;*}
PATTERN=${line#*;}
echo $COMMAND
echo $PATTERN
And the output would be:
this “is” a command
this “is” a pattern
32 comments
Comment by mads on June 15, 2006 at 9:15 am
This one should win a price… I works great and is noce and simple…
Comment by kerpz on July 23, 2006 at 11:55 pm
very nice.
Tnx for sharing …
Comment by Tako on August 4, 2006 at 9:28 am
Brilliant. Solved a big one for me
Comment by Anonymous on August 23, 2006 at 2:05 pm
you rock.
Comment by RAGHU on August 24, 2006 at 7:34 pm
EXCELENT, FANTASTIC, DONE
Comment by Hameed on October 25, 2006 at 12:06 am
Just what I needed!
Comment by bart on November 14, 2006 at 6:34 pm
very nice, used it for a simply archive handling bash script i wrote and put on my site
Comment by nihilist on February 6, 2007 at 12:25 pm
The only problem is that it doesn’t deal with multiple instancse of the separator character. What then?
Comment by Anton on February 13, 2007 at 12:27 am
nihilist,
Then you break out some perl or sed regex action and break it apart accordingly.
Comment by Acácio on February 22, 2007 at 6:04 pm
Outstanding!
Very usefull when splitting configuration files like:
PARAM=VALUE
PARAM=VALUE
.
.
.
Congratulations!
Comment by Jake on February 26, 2007 at 6:09 pm
This is so much more elegant than a nasty sed/awk expression. Thanks for improving my code!
Comment by MMx on April 17, 2007 at 8:28 am
@nihilist:
If you have multiple separator characters, like this:
string1;string2;string3
then you can split it this way:
original=’string1;string2;string3′
part1=${original%%;*}; rest=${original#*;}
part2=${rest%%;*}; rest=${rest#*;}
part3=${rest%%;*};
This should work for arbitrary number of parts.
Comment by oli on June 7, 2007 at 1:25 am
very nice … thanks
How to do if I have 3 tags (or more) like
line=’this “is” a command;this “is” a pattern;this “is” a bla’
COMMAND=${line%;*}
PATTERN=${line#*;}
echo $COMMAND
echo $PATTERN
Comment by v01d on June 7, 2007 at 1:39 am
nice job! i’ll use it for my scripting. thanks!
Comment by Anton on June 11, 2007 at 1:04 pm
@oli:
I’d just use ‘cut -d”;” -f1′ (and 2 and 3) to get each element then.
COMMAND=$(echo $line | cut -d”;” -f1)
PATTERN=$(echo $line | cut -d”;” -f2)
BLAH=$(echo $line | cut -d”;” -f3)
I am sure there is a way to split it properly, but I don’t recall how.
Comment by Jesper on June 20, 2007 at 4:35 am
Great! I use it to test if a site is changed (blackboard is down so when it changes I want to know)
Comment by Mark on July 19, 2007 at 10:10 pm
Thanks for the way here.
And I would like to share the way for 3 tag line, I tested this and used it.
COMMAND=${line%;*;*}
PATTERN=${line#*;}
PATTERN=${PATTERN%;*}
BLAH=${line#*;*;}
Trackback by et lux in tenebris lucet on November 5, 2007 at 3:03 pm
Splitting a string in bash…
I found this little trick to split a string in bash, so I’m sharing. Maybe it’s obvious to some people, but I don’t do a lot of shell scripting, so it was helpful to me.
http://anton.lr2.com/archives/2006/04/10/bash-split-a-string-wit…
Comment by Federico on December 30, 2007 at 4:09 am
Than you very much for this hint! It saved me from some tricky shell scripting
Comment by jerik on February 10, 2008 at 8:20 am
If I am right, this just works if you know how much delimiter are in the string you wish to split. Nice would be if this should work without knowing this…
cheers — jerik
Comment by steadyonabix on March 17, 2008 at 7:43 am
Very elegant, you are no bookmarked!
Many thanks
Comment by Tim K on June 6, 2008 at 10:00 am
Thanks, you saved me lot of time and valuable bytes!
Comment by red_team316 on August 24, 2008 at 1:57 am
You sir are Awesome! Not that this makes me enjoy bash any more(I prefer real programming languages), but this is much more understandable than that sed/awk stuff.
Bookmarked, Stumbled, Saved.
Comment by eureka tips on September 1, 2008 at 2:53 am
This cool tip was a lot helpful one…..I did a srch for my problem of interpreting a .CSV and this works like a charm
Comment by Jim Hertzler on September 5, 2008 at 9:39 am
#!/bin/bash
# Split the command line argument on the colon character.
IFS=”:”; declare -a Array=($*)
echo “Array[0]=${Array[0]}”
echo “Array[1]=${Array[1]}”
echo “Array[2]=${Array[2]}”
echo “Array[3]=${Array[3]}”
Comment by Anton on September 5, 2008 at 9:46 am
Jim,
Thanks! I hadn’t known about the IFS internal variable.
Comment by Jim Hertzler on September 5, 2008 at 4:25 pm
Go to:
http://www.linuxquestions.org/questions/programming-9/bash-shell-script-split-array-383848/?posted=1#post3270996
And see:
IP=1.2.3.4; IP=(${IP//./ }); Rev=${IP[3]}.${IP[2]}.${IP[1]}.${IP[0]}
Comment by alt on May 28, 2009 at 6:01 am
Here’s yet another take on it:
Splitting strings in Bash
http://codesnippets.joyent.com/posts/show/2016
Comment by Harald Strack on May 29, 2009 at 4:00 am
Hi,
redefinig IFS did work only on Linux, not on Solaris. So I wrote
a loop to split the input data into an array.
#!/bin/bash
declare -a Array
original=’string1 with spaces ~string2~string3~;; special chars \\;~last thing’
rest=$original
i=0
#create Array from line separated by ~
while true; do
restTmp=$rest
part1=${rest%%~*}; rest=${rest#*~}
Array[$i]=”$part1″
#echo $rest
i=`expr $i + 1`
if [ "$rest" == "$restTmp" ]; then
break
fi
done
#access Array
echo “Array[0]=${Array[0]}”
echo “Array[1]=${Array[1]}”
echo “Array[2]=${Array[2]}”
echo “Array[3]=${Array[3]}”
echo “Array[4]=${Array[4]}”
br
Harald Strack
Comment by andu on December 20, 2009 at 8:37 pm
somethings big things really come in small packages
great thing
Comment by knightEknight on June 30, 2010 at 9:55 am
# Using your original example I derived a way to loop thru a tokenized string:
#!/bin/bash
STR=”a,b,cc,ddd,ee,f,gg”
TOKEN=”"
echo STR: $STR
echo “Tokens:”
until [ "$STR" == "$TOKEN" ]; do
TOKEN=${STR%%,*}
STR=${STR#*,}
echo $TOKEN
done
Comment by aGuy on June 30, 2011 at 11:16 pm
a=”a b c d e”; arr=(${a// / }); echo ${arr[4]}