0

I have a problem similar to the one solve in this question: How do I split a string on a delimiter in Bash? .

The real difference is that I'm targeting the sh and ksh shell so, for example, I can't use the <<< redirection.

To recap my problem I have the content of a variable that is

VALUES="
val1    ;val2    ;val3
another1;another2;another3
"

so clearly the whitespace and ; are the characters that I would like to get rid of.

I also have to use this values as they appear in a 3 by 3 basis, 3 at the time, but I assume that for that I can simply use $1,$2 and $3 after the expansion plus a shift 3 at the end of each cycle.

Thanks.

Community
  • 1
  • 1
user2485710
  • 9,451
  • 13
  • 58
  • 102
  • @blueberryfields I guess that that will work, but it would be nice to discuss something that wasn't requiring any external tool, just to see if this is possible with the `sh` or `ksh`, using an external tool it's not really like targeting a specific shell, it's just ... using an external tool. – user2485710 Mar 25 '14 at 20:41
  • Huh? The accepted answer for that other question uses pure shell, no external tools (though Awk is usually available in some form) and no Bash. – tripleee Mar 25 '14 at 21:01
  • @tripleee I guess that I read that `<<` as `<<<`; but you are right, that should work too, I missed that somehow ... – user2485710 Mar 25 '14 at 21:05
  • @tripleee but that solution doesn't really cope that well with cycles and iterations, the solution given here does. – user2485710 Mar 25 '14 at 21:11

2 Answers2

4
VALUES="
val1    ;val2    ;val3
another1;another2;another3
"
echo "$VALUES" | while IFS=' ;' read v1 v2 v3; do 
    [[ -z $v1 && -z $v2 && -z $v3 ]] && continue
    echo "v1=$v1  v2=$v2  v3=$v3"
done
v1=val1  v2=val2  v3=val3
v1=another1  v2=another2  v3=another3

Re-reading your question, you're talking about arrays. Here you go:

typeset -a values
typeset -i i=0
echo "$VALUES" | while IFS=' ;' read v1 v2 v3; do
    [[ -z $v1 && -z $v2 && -z $v3 ]] && continue
    values[i]=$v1
    values[i+1]=$v2
    values[i+2]=$v3
    ((i+=3))
done

for i in "${!values[@]}"; do printf "%d\t%s\n" $i "${values[i]}"; done
0   val1
1   val2
2   val3
3   another1
4   another2
5   another3
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
2

You can use awk and reduce all the complexity:

echo "$VALUES"|awk -F' *; *' 'NF>1{print $1, $2, $3}'
val1 val2 val3
another1 another2 another3
anubhava
  • 761,203
  • 64
  • 569
  • 643
  • thanks, the problem with this is that I don't really have to print the values, and I would prefer to simply not use external tools, I would like to create something more like an array of values and shift them 3 by 3 when reading. – user2485710 Mar 25 '14 at 20:53