2013-06-25 66 views
1

我在使用shell腳本中的grep命令時遇到問題。其實我有一個文件(PCF_STARHUB_20130625_1),其中包含以下記錄。grep命令不是搜索完整模式

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 

而且我有存儲在一個變量(INPUT_FILE_T)的模式,並希望從文件(PCF_STARHUB_20130625_1)搜索模式。對於我已經使用以下命令

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

上述命令的輸出來瞭如下

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

我在輸出的兩個問題,第一個是,只有一個條目是表示在輸出端(它應該包含兩個條目),第二個問題是,輸出包含「PCF_STARHUB_20130625_1:」不應該出現。輸出應該像下面那樣

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 

除了grep請問有什麼技術請告訴我。

請幫我解決這個問題。

回答

0

在我input.txt已經複製您的數據:

$> (export INPUT_FILE_T="SH.*US\.*"; grep -h ${INPUT_FILE_T} input.txt) 
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 

編輯

如果你絕對必須使用glob模式,有可能是一種實用工具,在那裏,這樣做,但我不不知道。下面的快速C程序將幫助:

#include <fnmatch.h> 
#include <stdio.h> 
#include <stdlib.h> 

#define MAX_LINE_LENGTH 4096 

int main(int argc, char**argv) 
{ 
    if (argc < 2) { return EXIT_FAILURE; } 

    FILE *in = stdin; 
    const char *pattern = argv[1]; 

    char line[MAX_LINE_LENGTH + 1]; 
    while (fgets(line, MAX_LINE_LENGTH, in)) 
    { 
     if (!fnmatch(pattern, line, 0)) 
     { 
      printf("%s", line); 
     } 
    } 
    return EXIT_SUCCESS; 
} 

編譯(上述程序的文件myfnmatch.c中是):

$> gcc -Wall myfnmatch.c -o myfnmatch 

爲例用法(注意stdininput.txt重定向):

(export INPUT_FILE_T="SH?*???????????????US.*"; ./myfnmatch ${INPUT_FILE_T} <./input.txt) 
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 
+0

感謝rectummelancolique您的答覆...但我不能改變搜索模式(不能使用'SH。* US \。*'而不是'SH?* ?????????????? US。*'),因爲它已經在數據庫。 – vishal

+0

在grep regexp中,'''不代表'任何東西'(至少根據我的'man grep'),這意味着'前面的項目是可選的,最多隻匹配一次'。看來你的模式是一個「glob」模式而不是正則表達式。所以你必須改變它才能使用grep。 – rectummelancolique

+0

如果?在grep表達式中沒有任何意思,那麼它爲什麼搜索一個模式,它不會搜索任何模式。 – vishal

0

您可以使用.*來任意匹配任何字符次數,因此您的搜索模式可以被簡化(最後一個通配符也沒有必要卡):

INPUT_FILE_T="SH.*US\." 

要從輸出中刪除的文件名,使用-h標誌到grep:

$ grep -h ${INPUT_FILE_T} PCF_STARHUB_20130625_1 
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 
+0

尤索林感謝您的答覆...但我不能改變搜索模式(不能使用SH。*美國\ *代替SH *????????????美國。*),因爲它已經在數據庫上傳播了。 – vishal

+0

好的。然後'grep -h'解決你的問題。 – Yossarian

+0

但問題依然在下,grep的是無法找到的第二圖案。 – vishal