Find the answer to your Linux question:
Results 1 to 5 of 5
Hi all, i have read in one site (i can put link, but is in Czech language ) that regular expressions have some kind of memory. If i understood it ...
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49

    regular expressions memory

    Hi all, i have read in one site (i can put link, but is in Czech language ) that regular expressions have some kind of memory. If i understood it propertly when i want to remebmer some part of regexp i just put it between \( and ) and then call it by \1 \2 \3 etc. where \$number is number of memored expression. So i tried some examples bud didnt work for me :

    lets say i want to know only UID and HOME from /etc/passwd so i tried followings:

    Code:
    grep -E "^[^:]*:[^:]*:\([^:]*):[^:]*:[^:]*:\([^:]*):[^:]*" /etc/passwd
    grep -E "^[^:]*:[^:]*:\([^:])*:[^:]*:[^:]*:\([^:])*:[^:]*" /etc/passwd
    but neither one works. I know i didnt call \1 and \2 but i dont know how.

    also tried append "end" string to end of all lines of file

    Code:
    sed -e 's/\(.*)/\1end/' file_name
    with the same result as prevouis.

    I know both tasks can be done using some other utils such as sed. But just for curiosity i want know more about regexp memory. Thanks a lot

  2. #2
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    The regular expression memory only matters for replacing strings (as with sed -e 's/.../.../'), not for simply matching (as with grep). The problem with your sed expression is that you don't backslash-escape all of the parentheses. Try this:
    Code:
    sed -e 's/\(.*\)/\1end/' /etc/passwd
    Surrounding part of the match in parentheses is called a "capture". Here we capture the entire line, and then replace it with the first capture (the entire line) and then the word end.

    For the record, to append something to a line using regular expressions, this is better:
    Code:
    sed -e 's/$/end/' FILE
    What this does is replace the "end of the line" (which isn't a real character) with the string given. This is better because it doesn't require any sort of capturing, and doesn't require any sort of complicated match with quantifiers.

    Does this make sense?
    DISTRO=Arch
    Registered Linux User #388732

  3. #3
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49
    Noticed that the block of text that to be memored must be in \(....\), works in sed, in grep still dont know how to print just \1 \2

  4. #4
    Trusted Penguin Cabhan's Avatar
    Join Date
    Jan 2005
    Location
    Seattle, WA, USA
    Posts
    3,230
    You cannot. That is not what grep does. grep takes a pattern, and prints lines from a file that match that pattern. It does not allow for substitution or printing your captures.

    What you could do is this:
    Code:
    egrep '^[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*:[^:]*' /etc/passwd | sed -e 's/^[^:]*:[^:]*:\([^:]*\):[^:]*:[^:]*:\([^:]*\):[^:]*/\1 \2/'
    This uses a technique called piping. What we do is run grep with the given pattern on /etc/passwd, so as to get all lines that match the pattern. The output of grep (all matching lines) is then passed into sed. sed extracts the information that we want, and just prints the two groups.

    Does this make sense?
    DISTRO=Arch
    Registered Linux User #388732

  5. #5
    Just Joined!
    Join Date
    Jul 2009
    Posts
    49
    Yes now its celar thanks a lot

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...