I want sed to omit all non-matching lines, and only output the replaced string (of the single/multiple intended line/s).
In other words: I've got a hay stack, and only want the needle returned, not all the hay which was searched and which remained unaltered.
Or again in other words: Search/replace a RegEx described string in a multi line string, and only get that string returned. (As it is possible with the PHP function http://www.php.net/manual/en/function.preg-replace.php )
My current workaround is to first filter with grep, and then pipe only the matching lines into sed for replacement:
echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | egrep "^Important1.*$" | sed -E "s/^Important1: *\b(.*)\b */\1/g"
# From the multiple line input I only want the "One One" (with pre/post whitespace removed, hence matching the word boundaries with "\b")
# And I want no "Bla bla" lines in the result!
But I'd like to have a single solution within sed. Or 开发者_运维百科is this out of intended sed usage, and should I therefore better use something else? Btw, issue: multiline sed using backreferences seemed somehow related, but I am not sure!
Following solution has been tested on both Mac & Linux.
You can use sed like this:
echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" |
sed -n 's/^Important1: *\([^ ]*\) */\1/p'
OUTPUT:
one
Explanation
sed -n 's/^Important1: *\([^ ]*\) */\1/p'
-n # quiet / silent
{
s/^Important1: *\([^\ ]*\) */\1/ # replace "Important1: one " with 1st group i.e. "one"
p # print the replaced text
}
sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'
Proof of Concept
$ echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -n '/^Important1.*$/s/^Important1: *\b\(.*\)\b */\1/p'
One
This sed command does what your combination of egrep and sed does:
echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla"
| sed -n -e "s/^Important1: *\b\(.*\)\b */\1/p"
You perform the substitution and only print lines that matched, after the substitution.
In order to keep your original expression:
sed -E "s/^Important1: *\b(.*)\b */\1/g"
you can use the -n
option for sed
and add the p
flag to the end of your s
command like this:
sed -En "s/^Important1: *\b(.*)\b */\1/gp"
proof:
echo -e "Bla\nBla\nImportant1: One \nBla\nImportant2: Two\nBla\nBla" | sed -En "s/^Important1: *\b(.*)\b */\1/gp"
The s command uses the following format:
sed OPTIONS... 's/regexp/replacement/flags'
The -n
or --silent
option suppresses automatic printing of pattern space 1.
The p
flag is used to print the new pattern space if a substitution was made2.
精彩评论