Jamie
Jamie

Reputation: 1

unterminated address regex while using sed

I am trying to use the sed command to find and print the number that appears between "\MP2=" and "\" in a portion of a line that appears like this in a large .log file

\MP2=-193.0977448\

I am using the command below and getting the following error:

sed "/\MP2=/,/\/p" input.log
sed: -e expression #1, char 12: unterminated address regex

Advice on how to alter this would be greatly appreciated!

Upvotes: 0

Views: 4096

Answers (3)

William Pursell
William Pursell

Reputation: 212654

awk is a better tool for this:

awk -F= '$1=="MP2" {print $2}' RS='\' input.log

Set the record separator to \ and the field separator to '=', and it's pretty trivial.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 755054

Superficially, you just need to double up the backslashes (and it's generally best to use single quotes around the sed program):

sed '/\\MP2=/,/\\/p' input.log

Why? The double-backslash is necessary to tell sed to look for one backslash. The shell also interprets backslashes inside double quoted strings, which complicates things (you'd need to write 4 backslashes to ensure sed sees 2 and interprets it as 'look for 1 backslash') — using single quoted strings avoids that problem.

However, the /pat1/,/pat2/ notation refers to two separate lines. It looks like you really want:

sed -n '/\\MP2=.*\\/p' input.log

The -n suppresses the default printing (probably a good idea on the first alternative too), and the pattern looks for a single line containing \MP2= followed eventually by a backslash.

If you want to print just the number (as the question says), then you need to work a little harder. You need to match everything on the line, but capture just the 'number' and remove everything except the number before printing what's left (which is just the number):

sed -n '/.*\\MP2=\([^\]*\)\\.*/ s//\1/p' input.log

You don't need the double backslash in the [^\] (negated) character class, though it does no harm.

Upvotes: 4

tripleee
tripleee

Reputation: 189936

If the starting and ending pattern are on the same line, you need a substitution. The range expression /r1/,/r2/ is true from (an entire) line which matches r1, through to the next entire line which matches r2.

You want this instead;

sed -n 's/.*\\MP2=\([^\\]*\)\\.*/\1/p' file

This extracts just the match, by replacing the entire line with just the match (the escaped parentheses create a group which you can refer back to in the substitution; this is called a back reference. Some sed dialects don't want backslashes before the grouping parentheses.)

Upvotes: 0

Related Questions