Using Pure Bash to Parse Strings

while looking through my snippets for a script to parse a simple “several fields to a line, one record to a line” type of data set, I realized I was probably over engineering the solution, the following is the result of a few whiles playing with a few ideas:
 
 

#!/bin/bash
ITEMS='field 1;field 2;field 3;field 4;field 5'
LEN=${#ITEMS}
while [ "$LEN" -gt "0" ]; do
	echo -------------
	echo ${LEN}
	echo "post:"${ITEMS}
	#get the shortest match from front of the source string
	# by matching the longest from the back of the source string
	THIS_FIELD=${ITEMS%%;*}
	#remove the match from the source string
	ITEMS=${ITEMS:$((${#THIS_FIELD}+1))}
	#calc the length of the source string
	LEN=${#ITEMS}
	#show results
	echo "anno:"${ITEMS}
	echo ${THIS_FIELD}
done

will output:

————-
39
post:field 1;field 2;field 3;field 4;field 5
anno:field 2;field 3;field 4;field 5
field 1
————-
31
post:field 2;field 3;field 4;field 5
anno:field 3;field 4;field 5
field 2
————-
23
post:field 3;field 4;field 5
anno:field 4;field 5
field 3
————-
15
post:field 4;field 5
anno:field 5
field 4
————-
7
post:field 5
anno:
field 5

 
 
the idea can be taken further by using an array:

#!/bin/bash
#declare the array
declare -a FIELDS
ITEMS='field 1;field 2;field 3;field 4;field 5'
LEN=${#ITEMS}
while [ "$LEN" -gt "0" ]; do
	echo -------------
	echo ${LEN}
	echo "post:"${ITEMS}
	#get the shortest match from front of the source string
	# by matching the longest from the back of the source string
	THIS_FIELD=${ITEMS%%;*}
	#remove the match from the source string
	ITEMS=${ITEMS:$((${#THIS_FIELD}+1))}
	#calc the length of the source string
	LEN=${#ITEMS}
	#store result in the array
	FIELDS[ (${#FIELDS[*]}) ]=${THIS_FIELD}
	#show results
	echo "anno:"${ITEMS}
	echo ${THIS_FIELD}
	echo ${FIELDS[ (${#FIELDS[*]}-1) ]}
done

echo -------------
#show the array count
echo ${#FIELDS[*]}
#show the array content
echo ${FIELDS[*]}

will output:

————-
39
post:field 1;field 2;field 3;field 4;field 5
anno:field 2;field 3;field 4;field 5
field 1
field 1
————-
31
post:field 2;field 3;field 4;field 5
anno:field 3;field 4;field 5
field 2
field 2
————-
23
post:field 3;field 4;field 5
anno:field 4;field 5
field 3
field 3
————-
15
post:field 4;field 5
anno:field 5
field 4
field 4
————-
7
post:field 5
anno:
field 5
field 5
————-
5
field 1 field 2 field 3 field 4 field 5

 
 
the final script fragment without the comments::

#!/bin/bash
ITEMS='field 1;field 2;field 3;field 4;field 5'
declare -a FIELDS
LEN=${#ITEMS}
while [ "$LEN" -gt "0" ]; do
	THIS_FIELD=${ITEMS%%;*}
	ITEMS=${ITEMS:$((${#THIS_FIELD}+1))}
	LEN=${#ITEMS}
	FIELDS[ (${#FIELDS[*]}) ]=${THIS_FIELD}
done

COUNT=0
while [ "$COUNT" -lt ${#FIELDS[*]} ]; do
	echo ${FIELDS[$COUNT]}
	COUNT=$(( ${COUNT}+1 ))
done

obviously you would want to change the “ITEMS” variable and do something meaningful in the second loop.

this was posted in the hope that it will be of some use to someone.

Leave a comment

  • Categories

  • Need Code Written?

  • Need a Coding Job?

  • Tags

  • Archives