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
This one should win a price… I works great and is noce and simple…
very nice.
Tnx for sharing …
Brilliant. Solved a big one for me
you rock.
EXCELENT, FANTASTIC, DONE
Just what I needed!
very nice, used it for a simply archive handling bash script i wrote and put on my site 🙂
The only problem is that it doesn’t deal with multiple instancse of the separator character. What then?
nihilist,
Then you break out some perl or sed regex action and break it apart accordingly.
Outstanding!
Very usefull when splitting configuration files like:
PARAM=VALUE
PARAM=VALUE
.
.
.
Congratulations!
This is so much more elegant than a nasty sed/awk expression. Thanks for improving my code!
@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.
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
nice job! i’ll use it for my scripting. thanks!
@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.
Great! I use it to test if a site is changed (blackboard is down so when it changes I want to know)
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#*;*;}
Pingback: et lux in tenebris lucet
Than you very much for this hint! It saved me from some tricky shell scripting 🙂
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
Very elegant, you are no bookmarked!
Many thanks
Thanks, you saved me lot of time and valuable bytes!
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.
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
#!/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]}”
Jim,
Thanks! I hadn’t known about the IFS internal variable.
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]}
Here’s yet another take on it:
Splitting strings in Bash
http://codesnippets.joyent.com/posts/show/2016
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
somethings big things really come in small packages
great thing 🙂
# 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
a=”a b c d e”; arr=(${a// / }); echo ${arr[4]}
I’m not sure if I understand the problem, however this will split the lines regardless of how many items:
‘echo $line | cut -d’;’ -f1- –output-delimiter=$’n”
‘-f1-‘ will print all items starting with the first one. Notice the dash after f1.
### Output ###
this “is” a command
this “is” a pattern
cut works if you can manage to escape all the quotes, double and single.
The built in string methods work regardless of quoting.