PDA

View Full Version : building an array from a non-fixed string



cbillson
August 1st, 2013, 11:13 AM
if i had a file that contained lines such as:


name=bob smith address=123 any st town=london phone=01234567890 notes=some notes about bob smith of any length containing potentially any data


I'm trying to get this data into an array, the real data contains many elements i'd like to strip out.

i've been playing around with this:



cat myfile | while read line
do
echo $line
IFS='=' read -ra ADDR <<< "$line"
for i in "${ADDR[@]}"; do
echo $i
done



however, it splits the data up as

$ADD[0] name
$ADD[1] bob smith address



IFS=' ='


Works a little too well :) and takes the space in every element, so i end up with an array of every single word..

Any help achieving this appreciated

ofnuts
August 1st, 2013, 01:32 PM
Do a sed first and replace '([^ =]+=)' by '\n\1' (ie, insert a line feed before anything like "foo="). Then each line is "foo=foo data".

cbillson
August 1st, 2013, 03:06 PM
Do a sed first and replace '([^ =]+=)' by '\n\1' (ie, insert a line feed before anything like "foo="). Then each line is "foo=foo data".

i'm not sure that will work for what i hope to achieve. However, thank-you very much for that command, it could come in extremely useful..

i'm thinking use SED in the way you describe to add a divider (|@: etc) then split down into an array using the code i've been playing with. this should leave me with an array of xxx=yyyy - i can work on that further from there.

thanks very much.

ofnuts
August 1st, 2013, 04:56 PM
i'm not sure that will work for what i hope to achieve. However, thank-you very much for that command, it could come in extremely useful..

i'm thinking use SED in the way you describe to add a divider (|@: etc) then split down into an array using the code i've been playing with. this should leave me with an array of xxx=yyyy - i can work on that further from there.

thanks very much.
Yes, adding a divider instead of a linefeed can do it, if you find a divider which is guaranteed to not occur in the data.

Vaphell
August 1st, 2013, 09:02 PM
associative arrays for the win


$ declare -A array
$ array=()
$ while IFS='=' read -r key value; do array+=( ["$key"]="$value" ); done < <( sed -r 's/ (\w+=)/\n\1/g' in.txt )
$ for k in "${!array[@]}"; do printf "%s: %s\n" "$k" "${array[$k]}"; done
notes: some notes about bob smith of any length containing potentially any data
name: bob smith
phone: 01234567890
address: 123 any st
town: london

edit: seeing that you need different delimiter

#!/bin/bash

declare -A arr

while read -r ln
do
arr=()
while IFS='=' read -rd '|' key value
do
arr+=( ["$key"]="$value" )
done < <( echo "$ln|" | sed -r 's/ (\w+=)/|\1/g' )
echo "#$((++i)): ${#arr[@]} field(s)"
for k in "${!arr[@]}"
do
printf "%s: %s\n" "$k" "${arr[$k]}"
done
done < in.txt


$ ./data2arr.sh
#1: 5 field(s)
notes: some notes about bob smith of any length containing potentially any data
name: bob smith
phone: 01234567890
address: 123 any st
town: london
#2: 5 field(s)
notes: some crap
name: jane doe
phone: 01234567890
address: 123 any st
town: prague