Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I am facing a problem while using the grep command in shell script. Actually, I have one file (PCF_STARHUB_20130625_1) which contains below records.

SH_5.55916.00.00.100029_20130601_0001_NUC.csv.gz|438|3556691115
SH_5.55916.00.00.100029_20130601_0001_Summary.csv.gz|275|3919504621
SH_5.55916.00.00.100029_20130601_0001_UI.csv.gz|226|593316831
SH_5.55916.00.00.100029_20130601_0001_US.csv.gz|349|1700116234
SH_5.55916.00.00.100038_20130601_0001_NUC.csv.gz|368|3553014997
SH_5.55916.00.00.100038_20130601_0001_Summary.csv.gz|276|2625719449
SH_5.55916.00.00.100038_20130601_0001_UI.csv.gz|226|3825232121
SH_5.55916.00.00.100038_20130601_0001_US.csv.gz|199|2099616349
SH_5.75470.00.00.100015_20130601_0001_NUC.csv.gz|425|1627227450

And I have a pattern which is stored in one variable (INPUT_FILE_T), and I want to search the pattern from the file (PCF_STARHUB_20130625_1). For that I have used below command

INPUT_FILE_T="SH?*???????????????US.*"
grep ${INPUT_FILE_T} PCF_STARHUB_20130625_1 

The output of above command is coming as below

PCF_STARHUB_20130625_1:SH_5.55916.00.00.100029_20130601_0001_US.csv.gz|349|1700116234

I have two problems in the output, first is, only one entry is shown in output (It should contain two entries) and second problem is, output contains "PCF_STARHUB_20130625_1:" which should not be came. Expected output should come like below

SH_5.55916.00.00.100029_20130601_0001_US.csv.gz|349|1700116234
SH_5.55916.00.00.100038_20130601_0001_US.csv.gz|199|2099616349

Is there any technique except grep please let me know.

share|improve this question
2  
SH?*??????US.* is a retarded regular expression, the solution is to change it. –  Sirch Jun 25 '13 at 10:33
    
Forget it, and can't delete it. –  ott-- Jun 25 '13 at 12:59
    
What, after I put a script together for you to let you use GLOBs in grep? :p –  Sirch Jun 25 '13 at 13:04
add comment

closed as too localized by Iain, Ward, mdpc, Scott Pack, Jenny D Jun 25 '13 at 19:44

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.If this question can be reworded to fit the rules in the help center, please edit the question.

3 Answers

Given your comment on Pascal's answer, what you want can't be done.

The string you quote (SH?*???????????????US.*) isn't a grep rexexp. It looks like it might be a shell-style glob, but in grep, the metacharacter that matches a single character isn't ?, it's ., and * doesn't mean "any number of any character".

So if I understand correctly, your question boils down to "I have this glob-style regular expression stored in a database, what tool can I use to evaluate it against some strings"; in that case, the answer is "not grep; you'll have to find - or write - a tool that understands the kind of regular expressions you've already fixated on".

References from the gnu grep man page:

The period . matches any single character.

and

Repetition

   A regular expression may be followed by one of several repetition operators:
   ?      The preceding item is optional and matched at most once.
   *      The preceding item will be matched zero or more times.
share|improve this answer
add comment

Use egrep and a propper regular expression like

"^SH[0-9._]*US\.csv\.gz.*$"
share|improve this answer
    
Thanks Pascal for your response... but I can't the change the searching pattern (can't use SH.*US\.* instead of SH?*???????????????US.*) as it is already feed on database. If any other technique(except grep) can be applied then please let me know –  Sumit Vedi Jun 25 '13 at 10:13
add comment

Thanks to a script by David W. in a stackoverflow question, the following perl script will convert your useless GLOB into a regex, which you can then use in grep. Save the script to glob2regex.pl and then you can

grep `./glob2regex.pl SH?*???????????????US.*` 

glob2regex.pl:

#!/usr/bin/perl

my $GLOB = $ARGV[0];
print glob2regex($GLOB);
print "\n";

sub glob2regex {
my $glob = shift;

my $regex = undef;
my $previousAstrisk = undef;

foreach my $letter (split(//, $glob)) {
    #
    #    ####Check if previous letter was astrisk
    #
    if ($previousAstrisk) {
        if ($letter eq "*") { #Double astrisk
            $regex .= ".*";
            $previousAstrisk = undef;
            next;
        } else {        #Single astrisk: Write prev match
            $regex .= "[^/]*";
            $previousAstrisk = undef;
        }
    }
    #
    #   ####Quote all Regex characters w/ no meaning in glob
    #
    if ($letter =~ /[\{\}\.\+\(\)\[\]]/) {
        $regex .= "\\$letter";
        #
        #   ####Translate "?" to Regular expression equivelent
        #
    } elsif ($letter eq "?") {
        $regex .= ".";
        #
        #   ####Don't know how to handle astrisks until  the next line
        #
    } elsif ($letter eq "*") {
        $previousAstrisk = 1;
        #
        #   ####Convert backslashes to forward slashes
        #
    } elsif ($letter eq '\\') {
        $regex .= "/";
        #
        #   ####Just a letter
        #
    } else {
        $regex .= $letter;
    }
}
#
#   ####Handle if last letter was astrisk
#
if ($previousAstrisk) {
    $regex .= "[^/]*";
}
#
#    ####Globs are anchored to both beginning and ending
#
$regex = "^$regex\$";
return $regex;
}
share|improve this answer
add comment

Not the answer you're looking for? Browse other questions tagged or ask your own question.