tags:

views:

63

answers:

4

Input:

hello world "22" bye world

I need a regex that will work in bash that can get me the numbers between the quotes. The regex should match 22.

Thanks!

+3  A: 

Hmm have you tried \"([0-9]+)\" ?

FrustratedWithFormsDesigner
nope this didn't work :(
MArio
Could you explain how/why it doesn't work for you?It works for me, but you have to capture group 1 (assuming you can do that). You could try other variations, such as `^.*\"([0-9]+)\".*$`.
FrustratedWithFormsDesigner
+1  A: 

In Bash >= 3.2:

while read -r line
do
    [[ $line =~ .*\"([0-9]+)\".* ]]
    echo "${BASH_REMATCH[1]}"
done < inputfile.txt

Same thing using sed so it's more portable:

while read -r line
do
    result=$(sed -n 's/.*\"\([0-9]\+\)\".*/\1/p')
    echo "$result"
done < inputfile.txt
Dennis Williamson
Why that `result=` / `echo $result` thing?
Marian
@Marian: Just demonstrating saving the results to a variable for further processing. If you want it to go to the screen, just do `sed ...` by itself. In my first example, the result is automatically placed in a variable. I simply made the second parallel the functionality of the first.
Dennis Williamson
A: 

There are not really regexes in bash itself. There are however some programs that can use regexes, amongst them grep and sed.

grep's main functionality is to filter lines that match a given regex, ie you give it some data to stdin or a file and it prints the lines that match the regex.

sed does transform data. It doesn't just return the matching lines, you can tell it what to return with the s/regex/replacement/ command. The output part can contain references to groups (\x where x is the number of the group), if you specify the -r option.

So what we need is sed. Your input contains some stuff (^.*), a ", some digits ([0-9]+), a ", and some stuff (.*$). We later need to reference the digits, so we need to make the digits a group. So our complete matching regex is: ^.*"([0-9]+)".*$. We want to replace that with only the digits, so the replacement part is just \1.

Building the complete sed command is left as an exercise to you :-)

(Note that sed does not transform lines that don't match. If your input is only the line you provided above, that's fine. If there are other lines you'd like to silently skip, you need to specify the option -n (no automatic printing) and add a n to the end of the sed expression, which instructs it to print the line. That way it only prints the matching line(s).)

Marian
"There are not really regexes in bash itself." - See the first example in my answer. There *are* really regexes in Bash itself. "Building the complete sed command is left as an exercise to you" - or you can see the second example in my answer for a complete `sed` command.
Dennis Williamson
@Dennis Williamson: Yes, I didn't know that `=~` thing works in bash. At the exercise: That was on purpose, I like people have to think themselves, too :)
Marian
+1  A: 

Pure Bash, no Regex. Number is in array element 1.

IFS=\"    # input field separator is a double quote now

while read -a line ; do
  echo -e "${line[1]}"
done < "$infile"
fgm
What's the `-e` for here?
Dennis Williamson