Replace All Lines That Do Not Contain Matched String

Replace All Lines That Do Not Contain Matched String

You can do it like this:

$ sed '/hello/!s/.*/match/' infile
match
hello random text in file
match
words in file hello
match
hello text in file can be
match

/hello/! makes sure we're substituting only on lines not containing hello (you had that right), and the substitution then replaces the complete pattern space (.*) with match.

Regular expression to match a line that doesn't contain a word

The notion that regex doesn't support inverse matching is not entirely true. You can mimic this behavior by using negative look-arounds:

^((?!hede).)*$

Non-capturing variant:

^(?:(?!:hede).)*$

The regex above will match any string, or line without a line break, not containing the (sub)string 'hede'. As mentioned, this is not something regex is "good" at (or should do), but still, it is possible.

And if you need to match line break chars as well, use the DOT-ALL modifier (the trailing s in the following pattern):

/^((?!hede).)*$/s

or use it inline:

/(?s)^((?!hede).)*$/

(where the /.../ are the regex delimiters, i.e., not part of the pattern)

If the DOT-ALL modifier is not available, you can mimic the same behavior with the character class [\s\S]:

/^((?!hede)[\s\S])*$/

Explanation

A string is just a list of n characters. Before, and after each character, there's an empty string. So a list of n characters will have n+1 empty strings. Consider the string "ABhedeCD":

    ┌──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┬───┬──┐
S = │e1│ A │e2│ B │e3│ h │e4│ e │e5│ d │e6│ e │e7│ C │e8│ D │e9│
└──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┴───┴──┘

index 0 1 2 3 4 5 6 7

where the e's are the empty strings. The regex (?!hede). looks ahead to see if there's no substring "hede" to be seen, and if that is the case (so something else is seen), then the . (dot) will match any character except a line break. Look-arounds are also called zero-width-assertions because they don't consume any characters. They only assert/validate something.

So, in my example, every empty string is first validated to see if there's no "hede" up ahead, before a character is consumed by the . (dot). The regex (?!hede). will do that only once, so it is wrapped in a group, and repeated zero or more times: ((?!hede).)*. Finally, the start- and end-of-input are anchored to make sure the entire input is consumed: ^((?!hede).)*$

As you can see, the input "ABhedeCD" will fail because on e3, the regex (?!hede) fails (there is "hede" up ahead!).

How to globally replace strings in lines NOT starting with a certain pattern

You just need to negate the match using !:

sed -i '/^##Input/! s/foo/bar/g' myfile

Regex replace - match and empty all lines not containing a specific character

Yes, you could anchor your pattern and use a negated character class.

Find: ^[^c]*$

Explanation:

^          # the beginning of the string
[^c]* # any character except: 'c' (0 or more times)
$ # before an optional \n, and the end of the string

How can I replace a pattern only on lines that do or do not contain another pattern?

To replace "blue" with "green" in lines that contain "red":

:g/red/s/blue/green

To do the replacement in lines that do not contain "red":

:g!/red/s/blue/green

Sed replacing pattern starts with but not contains string

$ awk -v new='NEW_VERSION' 'f{$0=$1 FS new} {f=(/^Unix-/ && !/keep/)} 1' file
Cygwin
value: c
Unix-keep
value: u
Linux
value: l
Unix-16
value: NEW_VERSION
Solaris
value: s
Unix-replace-1
value: NEW_VERSION
Unix-replace-2
value: NEW_VERSION

Delete all lines not containing string in Sublime

For Sublime use:

1 - CTRL+H
2 - Click Regular Expressions (check ps below)

3 - Find What: ^163.33.74.115.*\n or ^(?!163.33.74.115).*\n for inverted matches

4 - Replace With: blank

5 - Click Replace All

Sample Image


GREP ANSWER:

The answer above should work fine, but I'd rather use grep, which is bundled with linux and mac, for windows get it here, i.e.:

1 - All lines except the ones containing 163.33.74.115:

grep -v 163.33.74.115 original.log > attack.log

2 - All lines containing 163.33.74.115:

grep 163.33.74.115 original.log > attack.log

Options:

-v, --invert-match        select non-matching lines

Remove all lines does not contain in other file

I would propose using the Join CSV function. @Abimanyu's regex method may work if you have less than 10 or so domains. More than that, it might take a while to process the data.

To prepare the document for joining, right click on the CSV/Sort toolbar and edit the User-defined separated format to use @ as the delimiter.

Customize window

Now on both file A and file B, change the CSV mode to User-defined separated. On the CSV/Sort toolbar, there is a button called "Join CSV".

Join CSV window

Join CSV options:

  • Make sure the correct documents are selected
  • Key Column is the email domain columns
  • In the list at the bottom, select the output columns, which should be column 1 and 2 from file A

Press the Join Now button, change CSV mode to Normal mode and you will get an output which looks like this:

0@gmail.com
igp@yahoo.com
vn@gmail.com
87@gmail.com

Regular expression to match strings that do NOT contain all specified elements

Nice question. It looks like you are looking for some AND logic. I am sure someone can come up with something better, but I thought of two ways:

^(?=(?!.*\btwo\b)|(?!.*\bthree\b)).*$

See the online demo

Or:

^(?=.*\btwo\b)(?=.*\bthree\b)(*SKIP)(*F)|^.*$

See the online demo

In both cases we are using positive lookahead to mimic the AND logic to prevent both words being present in a text irrespective of their position in the full string. If just one of those words is present, the string will pass.



Related Topics



Leave a reply



Submit