Sed: Matching on 2 Patterns on the Same Line

SED: multiple patterns on the same line, how to match/parse first one

This might work for you:

echo "bla bla bla NUM:09011111111 bla bla bla bla NUM:08022222222 bla bla bla" |
sed 's/NUM:/\n&/g;s/[^\n]*\n\(NUM:[0-9]*\)[^\n]*/\1 /g;s/.$//'
NUM:09011111111 NUM:08022222222

The problem you have is understanding that the .* is greedy i.e. it matches the longest match not the first match. By placing a unique character (\n sed uses it as a line delimiter so it cannot exist in the line) in front of the string we're interested in (NUM:...) and deleting everything that is not that unique character [^\n]* followed by the unique character \n, we effectively split the string into manageable pieces.

Output text between two patterns on the same line using sed command

For your current input you may use this sed:

sed 's/.*begin \(.*\) end.*/\1/' file

not sure what is wrong

Difference is use of .* after end that matches text after last end and discards in substitution.


However for your 2nd part if there are two end words, sed command won't work correctly as it will find last end due to greedy matching of .*.

e.g if your input is:

this is begin not sure what is wrong end and why not end

Then following awk would work better:

awk -F 'begin | end' '{print $2}' file

not sure what is wrong

sed to replace multiple pairs of identical pattern on same line

You should be able to get off with a single sed expression:

# ERE
sed -E 's/([^`$]|^)(\${1,2}[^`$]+\${1,2})([^`$]|$)/\1`\2`\3/g' test.txt

# or, if you prefer BRE (but only with GNU sed)
sed 's/\([^`$]\|^\)\(\$\{1,2\}[^`$]\+\$\{1,2\}\)\([^`$]\|$\)/\1`\2`\3/g' test.txt

gives you:

some text `$\alpha$` some text `$\alpha$` some text
some text `$\beta$` some text
some text `$\gamma$`.
some text `$\delta$`
`$\epsilon$` some text `$\epsilon$`
`$\mu$`

some text `$a$` some text `$a$` some text
some text `$b$` some text
some text `$c$`.
some text `$d$`
`$e$` some text `$e$`
`$f$`

`$$\Alpha$$`
`$$\Beta$$`

`$$A$$`
`$$B$$`

We match three groups:

  • prefix: a single non-backtick or non-dollar or line beginning
  • the meat: one or two $, followed by content, followed by one/two $
  • suffix: same as prefix, except we match line ending

then print them out, quoting with backticks only the middle group. We need to anchor on those prefix and suffix to avoid that double quoting you're experiencing.

Note that the POSIX BRE (basic regular expression) form above uses several GNU extensions, namely: anchoring on line beginning and line ending used in the middle of expression (and not as the first/last character in pattern), alternation (\|) and one-or-more duplication operator (\+). If you need this expression to work in POSIX BRE, you'll need to break it into several (i.e. 3) subexpressions and use \{1,\} instead of \+.

But also note that the POSIX ERE (extended regular expressions) form given should work in all modern sed environments, on both GNU and BSD systems.

Using sed to match on multiple patterns with one expression, and delete until a blank line

Try:

ifconfig -a | sed -r '/(eth[0-9]{1,2}:|eth100:|lo)/,/^$/d'

{1,2} means one or two of the preceding. So, eth[0-9]{1,2} matches eth followed by one or two numbers.

(A|B|C) matches either A or B or C. So, (eth[0-9]{1,2}:|eth100:|lo) matches either eth with one or two numbers or eth100 and a colon or lo.

The used -r for extended regular expressions (ERE). Without -r, sed defaults to basic regular expressions (BRE). ON GNU sed, BRE work the same but at the cost of extra backslashes:

ifconfig -a | sed '/\(eth[0-9]\{1,2\}:\|eth100:\|lo\)/,/^$/d'

BSD/OSX

BSD (OSX) sed does not recognize the -r option. To get extended regex, use -E instead:

ifconfig -a | sed -E '/(eth[0-9]{1,2}:|eth100:|lo)/,/^$/d'

-E will also work with recent versions of GNU sed.

Find two string in same line and then replace using sed

/files|no/ means to match lines with either files or no, it doesn't require both words on the same line.

To match the words in either order, use /files.*no|no.*files/.

sed -i -r -e '/files.*no|no.*files/s/red/green/' "$file"

Notice that you need another / at the end of the pattern, before s, and the s operation requires / at the end of the replacement.

And you need the -r option to make sed use extended regexp; otherwise you have to use \| instead of just |.

Match the same pattern n times on the same line using sed

This might work for you (GNU sed):

sed 's/\(<\/div>\)[^<]*/\1\n/;/^</P;D' file

Replace a </div> followed by zero or more characters that are not a < by itself and a newline. Print only lines that begin with a <.

SED: insert a word/string between two patterns in the SAME LINE

Use capture groups.

sed -e 's/(pattern1)(pattern2)/\1new_word\2/'

\1 is replaced with whatever matched the first pattern, \2 gets whatever matched the second pattern.



Related Topics



Leave a reply



Submit