0

I am new to regex and I am trying to write a regex in a bash script . I am trying to match line with a regex which has to return the second word in the line .

regex = "commit\s+(.*)"
line = "commit 5456eee"
if [$line =~ $regex] 
then
 echo $2
else 
 echo "No match"
fi

When I run this I get the following error:-

man.sh: line 1: regex: command not found
man.sh: line 2: line: command not found

I am new to bash scripting . Can anyone please help me fix this . I just want to write a regex to capture the word that follows commit

2
  • Note: the =~ operator is only valid with double bracket syntax [[ .. ]] Commented Apr 15, 2015 at 9:35
  • Your seeing command not found because you have a space between the variable name and the value. Example: regex = "commit\s+(.*)" should become regex="commit\s+(.*)". See answers below. Commented Apr 15, 2015 at 9:54

6 Answers 6

1

You don't want a regex, you want parameter expansion/substring extraction:

line="commit 5456eee"
first="${line% *}"
regex="${line#* }"
if [[ $line =~ $regex ]] 
    then
    echo $2
else 
    echo "No match"
fi

$first == 'commit', $regex == '5456eee'. Bash provides all the tools you need.

Sign up to request clarification or add additional context in comments.

Comments

1

If you really only need the second word you could also do it with awk

line = "commit 5456eee"
echo $line | awk '{ print $2 }'

or if you have a file:

cat filename | awk '{ print $2 }'

Even if it's no bash only solution, awk should be present on most linux os's.

2 Comments

How do i copy the output into a variable?
You could redirect it with another pipe, output it to a file using cat filename | awk '{ print $2 }' > filename or just do output=$(cat filename | awk '{ print $2 }') to capture output inside the $output var.
0

You should remove the spaces around the equals sign, otherwise bash thinks you want to execute the regex command using = and "commit\s+(.*)" as arguments. Then you should remove the spaces also in the if condition and quote the strings:

$ regex="commit\s+(.*)"
$ line="commit 5456eee"
$ if [ "$line"=~"$regex" ]
> then
>   echo "Match"
> else 
>   echo "No match"
> fi
Match

2 Comments

There is no =~ operator for [ .. ], only [[ .. ]]
You can use =~ like that as long you don't have spaces around the operator.
0

maybe you didn't start your script with the

#!/bin/sh

or

#!/bin/bash

to define the language you're using... ? It must be your first line. then be careful, spaces are consistant in bash. In your "if" statement, it should be :

if [ $line =~ $regex ]

check this out and tell us more about the errors you get

Comments

0

if you make this script to a file like test.sh

and execute like that :

test.sh commit aaa bbb ccc
   $0     $1    $2  $3  $4

you can get the arguments eassily by $0 $1...

Comments

0

A simple way to get the resulting capture group that was matched (if there is one) is to use BASH_REMATCH, which puts the match results into it's own array:

regex=$"commit (.*)"
line=$"commit 5456eee"
if [[ $line =~ $regex ]] 
then
 match=${BASH_REMATCH[1]}
 echo $match
else 
 echo "No match"
fi

Since you have only one capture group it will be defined within the array as BASH_REMATCH[1]. In the above example I've assigned the variable $match to the result of BASH_REMATCH[1] which returns:

5456eee

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.