Reputation: 1
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
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
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
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