2017-07-26 150 views
-2

我有2個文本文件多字符串搜索和替換

File1有超過400K行。每一行類似於此示例:

hstor,table,"8bit string",ABCD,0000,0,4,19000101,today 

文件2有新的8位字符串列表,以取代目前在那些文件1,而在文件1保持休息。

所以從文件1

hstor,table,"OLD 8bit string",ABCD,0000,0,4,19000101,today 

hstor,table,"NEW 8bit string",ABCD,0000,0,4,19000101,today 

我不能用sed 400K次

我怎麼能腳本這使所有在文件1的OLD 8位字符串替換在file2中列出新的8位字符串?

+3

你嘗試什麼嗎?你目前的研究工作是什麼?你覺得哪裏停滯不前? :)對於未來:請嘗試考慮使用適當的標點符號。它使你的問題更具可讀性。 – Markus

+1

您可以使用'join'命令來解決您的問題。 「男人加入」是你的朋友。 – codeforester

+2

「我不能sed 400K次」 - 爲什麼? – klutt

回答

1

這可能爲你工作(GNU SED):

sed 's#.*#s/[^,]*/&/3#' file2 | cat -n | sed -f - file1 

該功能可將文件2成sed腳本文件,然後運行它的文件1。

第一個sed腳本獲取file2中的每一行並將其更改爲替換命令,該命令用目標文件2的內容替換目標中的第三個字段。

這是輸入到cat命令中,該命令插入sed腳本將使用的行號來尋址每個替換命令。

最終的sed命令使用/ dev/stdin讀入sed腳本並根據輸入文件file1運行它。

+0

似乎工作。然而,花費20分鐘才能做到10%,所以如果OP需要做的事情不止一次,我可以理解它是否需要很長時間。 – klutt

0

如果您需要多次執行此操作並且性能很重要,我在C中編寫了一個程序來執行此操作。它是this code的修改版本。我知道你沒有使用任何C-tag,但我的印象是你的主要擔心是完成工作。

注意:

我對此不承擔任何責任。這是一個很快的黑客攻擊,我確實假設了一些東西。一個假設是您要替換的字符串不包含任何逗號。另一個是沒有行超過100個字節。第三個假設是輸入文件分別命名爲filerep。如果您想嘗試一下,請務必在之後檢查數據。它寫入標準輸出,所以你只需將輸出重定向到一個新文件。它在大約兩秒內完成工作。

下面是代碼:

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

int main() 
{ 

    /* declare a file pointer */ 
    FILE *infile; 
    FILE *replace; 
    char *buffer; 
    char *rep_buffer; 
    long numbytes; 
    long rep_numbytes; 

    /* open an existing file for reading */ 
    infile = fopen("file", "r"); 
    replace = fopen("rep", "r"); 

    /* quit if the file does not exist */ 
    if(infile == NULL) 
    return 1; 
    if(replace == NULL) 
    return 1; 

    /* Get the number of bytes */ 
    fseek(infile, 0L, SEEK_END); 
    numbytes = ftell(infile); 
    fseek(replace, 0L, SEEK_END); 
    rep_numbytes = ftell(replace); 

    /* reset the file position indicator to 
    the beginning of the file */ 
    fseek(infile, 0L, SEEK_SET); 
    fseek(replace, 0L, SEEK_SET); 

    /* grab sufficient memory for the 
    buffer to hold the text */ 
    buffer = (char*)calloc(numbytes, sizeof(char)); 
    rep_buffer = (char*)calloc(rep_numbytes, sizeof(char)); 

    /* memory error */ 
    if(buffer == NULL) 
    return 1; 
    if(rep_buffer == NULL) 
    return 1; 

    /* copy all the text into the buffer */ 
    fread(buffer, sizeof(char), numbytes, infile); 
    fclose(infile); 
    fread(rep_buffer, sizeof(char), rep_numbytes, replace); 
    fclose(replace); 


    char line[100]={0}; 
    char *i=buffer; 
    char *r=rep_buffer; 

    while(i<&buffer[numbytes-1]) { 
    int n; 

    /* Copy from infile until second comma */ 
    for(n=0; i[n]!=','; n++); 
    n++; 
    for(; i[n]!=','; n++); 
    n++; 
    memcpy(line, i, n); 

    /* Copy a line from replacement */ 
    int m; 
    for(m=0; r[m]!='\n'; m++); 

    memcpy(&line[n], r, m); 

    /* Skip corresponding text from infile */ 
    int k; 
    for(k=n; i[k]!=','; k++); 

    /* Copy the rest of the line */ 
    int l; 
    for(l=k; i[l]!='\n'; l++); 
    memcpy(&line[n+m], &i[k], l-k); 

    /* Next line */ 
    i+=l; 
    r+=m+1; 

    /* Print to stdout */ 
    printf("%s", line); 
    }  


    /* free the memory we used for the buffer */ 
    free(buffer); 
    free(rep_buffer); 
}