tags:

views:

281

answers:

5

What is a regex I can write in bash for parsing a line and extracting text that can be found between two | (so that would be ex: 1: |hey| 2: |boy|) and keeping those words in some sort of array?

A: 

Use sed -e 's,.*|\(.*\)|.*,\1,'

syker
+1  A: 
$ foundall=$(echo '1: |hey| 2: |boy|' | sed -e 's/[^|]*|\([^|]\+\)|/\1 /g')
$ echo $foundall
hey boy
$ for each in ${foundall}
> do
>  echo ${each}
> done
hey
boy
Stephen P
A: 

In your own answer, you output what's between the last pair of pipes (assuming there are more than two pipes on a line).

This will output what's between the first pair:

sed -e 's,[^|]*|\([^|]*\)|.*,\1,'

This will output what's between the outermost pair (so it will show pipes that appear between them):

sed -e 's,[^|]*|\(.*\)|.*,\1,'
Dennis Williamson
A: 
#!/bin/bash

_str="ex: 1: |hey| 2: |boy|"
_re='(\|[^|]*\|)(.*)'  # in group 1 collect 1st occurrence of '|stuff|';
                       # in group 2 collect remainder of line. 

while [[ -n $_str ]];do
   [[ $_str =~ $_re ]]
   [[ -n ${BASH_REMATCH[1]} ]] && echo "Next token is '${BASH_REMATCH[1]}'"
   _str=${BASH_REMATCH[2]}
done

yields

Next token is '|hey|'
Next token is '|boy|'
Kevin Little
+2  A: 

no need complicated regular expression. Split on "|", then every 2nd element is what you want

#!/bin/bash
declare -a array
s="|hey| 2: |boy|"
IFS="|"
set -- $s
array=($@)
for((i=1;i<=${#array[@]};i+=2))
do
 echo ${array[$i]}
done

output

$ ./shell.sh
hey
boy

using awk

$ echo s="|hey| 2: |boy|" |  awk -F"|" '{for(i=2;i<=NF;i+=2)print $i}'
hey
boy
ghostdog74
+1 Nice use of IFS, set and (). But, this approach won't work if the left and right delimiters differ (say, '<' and '>') and the order is meaningful, or the delimiter were multi-character (say, "--"). A regex approach is more general/flexible, IMHO.
Kevin Little
to make it more flexible is not difficult either. until that is required by OP, it will be left as it is.
ghostdog74