How to skip lines matching a string

前端 未结 2 1441
我在风中等你
我在风中等你 2020-12-10 05:00

I\'m new to sed, so maybe someone can help me out. I\'m modifying some files and want to skip all lines that have the strings \"def\" or \"page.\" on them. How do I do this

相关标签:
2条回答
  • 2020-12-10 05:36

    If I understood well, you want to apply some changes to various lines except some line matching a regex, right? In this case, let us suppose I have the following file:

    $ cat file
    this is a def
    this has no d e f
    this is a page by the way
    but this is no p a g e as we know ito
    

    We want to replace all this by that but ignore the lines containing by def or page. So first we delete the lines starting with def or page:

    /def/d;/page/d;
    

    Then we apply our operation as usual:

    s/this/that/g
    

    The result is:

    $ sed '/def/d;/page/d;s/this/that/g' file
    that has no d e f
    but that is no p a g e as we know ito
    

    But if by "skip" you mean "do not apply my operations", just negate the address:

    $ sed -E '/(def|page)/!s/this/that/g' file
    this is a def
    that has no d e f
    this is a page by the way
    but that is no p a g e as we know ito
    

    The above statement correct. Interestingly, the 'or' operator is associated with "extended regular expression." So you must specify -E for "extended regular expression" because sed, by default, uses only "basic regular expressions."

    For example, the following statement doesn't work:

    $ sed -e '/(def|page)/!s/[A-Za-z_]*login[A-Za-z_]*/page.&/g' < file > new_file
    

    But this statement below works:

    $ sed -E '/(def|page)/!s/[A-Za-z_]*login[A-Za-z_]*/page.&/g' < file > new_file
    
    0 讨论(0)
  • 2020-12-10 05:51

    AFAIK You can't (easily) negate matching lines with sed, but something like will almost work:

    sed '/\([^d][^e][^f][^ ]\)\|\([^p][^a][^g][^e]\)/ s/foo/bar/' FILE
    

    it replaces foo with bar on the lines which does not contain def or page but catch is that "matching" lines must be at least 4 char long.

    A better solution is to use awk, e.g.:

    awk '{ if ($0 !~ /def|page/) { print gensub("foo","bar","g") } else { print } }' FILE
    

    HTH

    0 讨论(0)
提交回复
热议问题