Find the answer to your Linux question:
Results 1 to 4 of 4
Hi gurus, I am trying to match records in following format: Code: (-,username,domain1.co.uk)\ (-,username,domain2.co.uk) either awk or perl must be used. I am using cygwin. I wrote following code which ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    Jul 2009
    Posts
    70

    Multi platform script perl or awk


    Hi gurus, I am trying to match records in following format:

    Code:
    (-,username,domain1.co.uk)\
    (-,username,domain2.co.uk)

    either awk or perl must be used. I am using cygwin. I wrote following code which works and matches both above entries:
    Code:
    awk 'BEGIN {musr="(-,username,[^)]+.co.uk)"} {if ($0~musr) print $0}' netgroup

    But if I try to modify this regexp to be more specific the output is nothing:

    # 1st: match record then last backslash and then match newline
    Code:
    "(-,username,[^)]+.co.uk)\\$"
    # 2nd: match new line immediatelly after record without backslash

    Code:
    "(-,username,[^)]+.co.uk)$"
    So i decided to rewrite script into perl, hoping that perl can deal with backslashes and end of line symbols. For this purpose I used a2p this way:

    Code:
    echo  'BEGIN {musr="(-,username,[^)]+.co.uk)"} {if ($0~musr) print $0}' | a2p.exe 
    #!/usr/bin/perl
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
        if $running_under_some_shell;
                            # this emulates #! processing on NIH machines.
                            # (remove #! line above if indigestible)
    
    eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;
                            # process any FOO=bar switches
    
    $, = ' ';               # set output field separator
    $\ = "\n";              # set output record separator
    
    $musr = '(-,username,[^)]+.co.uk)';
    
    while (<>) {
        chomp;      # strip record separator
        if ($_ =~ $musr) {
            print $_;
        }
    }

    This generated perl script also matches both entries, however if I try modify this script to more specific I get the following errors:

    1st:
    Code:
    $musr = "(-,username,[^)]+.co.uk)\\";
    Trailing \ in regex m/(-,username,[^)]+.co.uk)\/ at perlmatch.pl line 18, <> line 1.

    2nd:
    Code:
    $musr = "(-,username,[^)]+.co.uk)$";
    Final $ should be \$ or $name at perlmatch.pl line 14, within string
    syntax error at perlmatch.pl line 14, near "= "(-,username,[^)]+.co.uk)$""
    Execution of perlmatch.pl aborted due to compilation errors.

    3rd:
    Code:
    $musr = "(-,username,[^)]+.co.uk)\$";
    [the output is nothing]

    What I am doing wrong ? My question is also pointing to fact that if somebody needs to use script on several platforms (aix, solaris, linux) than using perl should be better approach that dealing with (non)GNU utils and various (g|n)awk versions etc. Regards

  2. #2
    Trusted Penguin
    Join Date
    May 2011
    Posts
    4,353
    Hi,

    I can't be certain what you are trying to match on. I think you are reading a file ("netgroup") and trying to match on lines containing only these two exact strings:

    Code:
    (-,username,domain1.co.uk)\
    (-,username,domain2.co.uk)
    not sure why you are talking about the new line char.

    anyway, assuming the above is true, and assuming you have a file called "netgroup" containing the above the strings, the following perl code works for me:

    Code:
    #!/usr/bin/perl
    use strict;
    use warnings;
    
    open(FH,'<','netgroup') or die "can't open netgroup: $!\n";
    while(<FH>) {
      chomp;        # remove newline char
      if(/^\(-,username,[^)]+.co.uk\)\\?$/){
        print 'MATCH: ',$_,"\n";
      }
    }
    close(FH);

  3. #3
    Just Joined!
    Join Date
    Jul 2009
    Posts
    70
    Actually I need to pass string into awk and create regular expression from this string and then using this created regular expresions to matching. AFAIK this can be done via "-v var=variableValue" syntax but as I mentioned it does not worked for me. Regarding [^)]+ syntax part I made a typo, the main idea was to find any character but not dot "." followed by "co.uk" probably the correct form should be: "\(-,username,[^.]+\.co\.uk\)$" for first record type and "\(-,username,[^.]+\.co\.uk\)\\$" for second. This works if i use it "inside" awk with "$0~//" syntax but not if I want to define this regexp in variable.

    Definition in vvariable:
    Code:
    awk 'BEGIN {musr="\(-,username,[^.]+\.co\.uk\)$"} {if ($0~musr) print $0}' netgroup
    awk: warning: escape sequence `\(' treated as plain `('
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: warning: escape sequence `\)' treated as plain `)'
    
    awk 'BEGIN {musr="\(-,username,[^.]+\.co\.uk\)\\$"} {if ($0~musr) print $0}' netgroup
    awk: warning: escape sequence `\(' treated as plain `('
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: warning: escape sequence `\)' treated as plain `)'
    
    awk -v musr="\(-,username,[^.]+\.co\.uk\)\\$"  '{if ($0~musr) print $0}' netgroup
    awk: warning: escape sequence `\(' treated as plain `('
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: warning: escape sequence `\)' treated as plain `)'
    awk: warning: escape sequence `\$' treated as plain `$'
    
    awk -v musr="\(-,username,[^.]+\.co\.uk\)$"  '{if ($0~musr) print $0}' netgroup
    awk: warning: escape sequence `\(' treated as plain `('
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: warning: escape sequence `\)' treated as plain `)'
    Wrong definition "inside" awk script
    Code:
    awk '{if ($0~"\(-,username,[^.]+\.co\.uk\)$")  {print $0}}' netgroup
    awk: warning: escape sequence `\(' treated as plain `('
    awk: warning: escape sequence `\.' treated as plain `.'
    awk: warning: escape sequence `\)' treated as plain `)'
    Correct definition "inside" awk script
    Code:
    awk '{if ($0~/\(-,username,[^.]+\.co\.uk\)$/)  {print $0}}' netgroup
                    (-,username,t-mobile.co.uk)
    
    awk '{if ($0~/\(-,username,[^.]+\.co\.uk\)\\$/)  {print $0}}' netgroup
                    (-,username,one2one.co.uk)\

    PS: Is there some tool in which you can highlight part of text and it will generate appropriate matching regular expression? I think it would be great to test/correct yourself. Regards
    Last edited by wakatana; 10-03-2012 at 11:18 PM.

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Newbie
    Join Date
    Jun 2012
    Location
    SF Bay area
    Posts
    204
    If I understand what you're trying to make, specifically that the lines you want to show are ones with only that pattern in the line, then this worked for me.

    Code:
    gawk '/^\(-,username,/ && /.co.uk\)$/'
    It matches any line that starts with "(-,username," and ends with ".co.uk)". If all you want to do it print them, then you don't even need to put any code after the pattern since the default action is to print the whole line.

    But I think you might want something more flexible? I just can't tell what you're looking for without a few more hints.

Posting Permissions

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