Find the line number which contains the pattern using custom regex delimiter

41,091

Solution 1

Stéphane gave you the sed solution:

sed -n  '\|file /etc|=' file 

If you're open to using other tools, you can also do

grep -n 'file /etc' file

That will also print the line itself, to get the line number alone try:

grep -n 'file /etc' file | cut -d: -f 1

Or, you can use perl:

perl -lne 'm|file /etc| && print $.' file 

Or awk:

awk '$0 ~ "file /etc" {print NR}'

Solution 2

In all context addresses, you have to escape the opening delimiter, unless you're using the default /. Any following occurrences that are escaped are treated as the literal character, not as the ending delimiter.

  • default delimiter:

    /start/,/end/{/pattern/d;}
    
  • custom delimiter:

    \#start#,\#end#{\#pattern#d;}
    

See the POSIX docs:

In a context address, the construction \cREc where c is any character other than a backslash or newline character, is identical to /RE/ If the character designated by c appears following a backslash, then it is considered to be that literal character, which does not terminate the RE. For example, in the context address \xabc\xdefx, the second x stands for itself, so that the regular expression is abcxdef.

Similar description in GNU sed man page:

/regexp/
       Match lines matching the regular expression regexp.      
\cregexpc
       Match lines matching the regular expression regexp.  
       The c may be any character.

and FreeBSD sed man page:

In a context address, any character other than a backslash (``\'')
or newline character may be used to delimit the regular expression.
The opening delimiter   needs to be preceded by a backslash unless it
is a slash.  For example, the   context address \xabcx is equivalent
to /abc/.  Also, putting a backslash character before   the delimiting
character within the regular expression causes the character to be
treated literally.  For example, in the context address \xabc\xdefx,
the RE delimiter is an ``x'' and the second ``x'' stands for itself,
so that the regular expression is ``abcxdef''.
Share:
41,091

Related videos on Youtube

jasiustasiu
Author by

jasiustasiu

Updated on September 18, 2022

Comments

  • jasiustasiu
    jasiustasiu over 1 year

    As in example I'm trying to get line numbers which contains the pattern. My pattern contains slashes so I wanted to add custom delimiter.

    This simple one works:

    sed -n '/file/=' temp.txt
    

    Using delimiter for string replace works too:

    sed 's|file|gile|' temp.txt
    

    but when I want to add delimiter to first example it doesn't:

    sed -n '|file /etc|=' temp.txt
    

    I know I can escape slashes but I would prefer to add custom delimiter. Any idea how to fix my command?

    • Admin
      Admin about 9 years
      sed -n '\|file /etc|='
    • Admin
      Admin about 9 years
      Thanks! What I found after your answer: \%regexp% (The % may be replaced by any other single character.) This also matches the regular expression regexp, but allows one to use a different delimiter than /. This is particularly useful if the regexp itself contains a lot of slashes, since it avoids the tedious escaping of every /. If regexp itself includes any delimiter characters, each must be escaped by a backslash ().
    • Admin
      Admin over 5 years
  • Brian Rasmussen
    Brian Rasmussen about 9 years
    Using the dot will find "etc" preceded by any character. Use a slash to be specific.
  • terdon
    terdon about 9 years
    @DennisWilliamson I have no idea why I used a dot in some of those. Must have been an artifact from my test runs. Thanks, fixed.