2013-06-24 3 views
1

Чтение строки в file1, если строка не существует в file2 напишите эту строку в новом файле.
Сравнение производится длиной хэш-строки.Сортировка хэш-значений по длине строк в текстовых файлах

значения хэш-функции в file1:

cf03189f5b05eb1a9658f80d7a0e9f02:_#.g} 
edbe6de8b3ee19b45e092147f57af7b8:]mNon 
47253940f843f258ffd265d13f365d70:/u'yv 
5701aa8e2aa7e1cfd16ca4076bd1732a:@AQ1z 
b3c0866e6fd56776bc4a18d3c87cc725:t$5OV 
7a1e6090568e076c55df9dc7abf356c6:[email protected] 
04046da33706518d9b15a38bcddb448e:!DFPk 

значения хэш-функции в file2:

edbe6de8b3ee19b45e092147f57af7b8:]mNon:str1 
47253940f843f258ffd265d13f365d70:/u'yv:2str 
b3c0866e6fd56776bc4a18d3c87cc725:t$5OV:3str1ng 

Это рабочий пример, написанные на C:

#include <stdio.h> 
#include <string.h> 

#define LINE_LENGTH 80 
typedef enum {FALSE=0,TRUE=1} BOOL; 
int main(int argc, char *argv[]) 
{ 
    FILE *fpin1 = NULL; 
    FILE *fpin2 = NULL; 
    FILE *fpout = NULL; 
    char line [LINE_LENGTH]={0}; 
    char line1[LINE_LENGTH]={0}; 
    BOOL bCheck = FALSE; 
    size_t ncHash = 0; 
    size_t count = 0; 

    if (argc != 4) 
    { 
     printf("Usage:%s <file1> <file2> <OutFile>\n", argv[0]); 
     return 1; 
    } 
    /* 
     Opening input files (file1 and file2) for reading in text mode. 
     The output file (OutFile) is open for writing. 
    */ 
    if(((fpin1=fopen(argv[1],"r"))==NULL) || 
     ((fpin2=fopen(argv[2],"r"))==NULL) || 
     ((fpout=fopen(argv[3],"w"))==NULL)) 
    { 
     printf("Error! Could not open files\n"); 
     return 1; 
    }  
    while(fgets(line, sizeof(line), fpin1)!=NULL) /* Read hash line from the first file1 */ 
    { 
     bCheck=FALSE; 
     while(fgets(line1, sizeof(line1), fpin2)!=NULL) /* Read hash line from the second file2 */ 
     { 
      if(!strncmp(line, line1, 38)) /* Compares 38 characters of the line in file1 to those of the file2 */ 
      { 
       bCheck=!bCheck; 
       break; 
      } 
     } 
     if(!bCheck) /* Does compared line are the same ? */ 
     { 
      fputs(line,fpout); /* Yes - write them in a file OutFile */ 
      ncHash++; /* Count identical lines */ 
     } 
     rewind(fpin2); /* Seek to the beginning of the file2 */ 
     count++;  /* Counting the read lines in file1 */ 
    } 
    printf("\nDone...\n"); 

    fclose(fpin1); 
    fclose(fpin2); 
    fclose(fpout); 
    return 0; 
} 

OutFile из программы:

cf03189f5b05eb1a9658f80d7a0e9f02:_#.g} 
5701aa8e2aa7e1cfd16ca4076bd1732a:@AQ1z 
7a1e6090568e076c55df9dc7abf356c6:[email protected] 
04046da33706518d9b15a38bcddb448e:!DFPk 

  • Я хочу знать, как писать в awk?
+1

Посмотрите на '' comm' или join' стандартные UNIX утилиты. –

+0

'join -v1 all <(cut -d: -f1,2 исключает)' – Kevin

ответ

3
awk -F: 'NR==FNR{a[$1,$2];next}!(($1,$2) in a)' excludes.txt all.txt 

Обратите внимание на изменение порядка файла аргументов.

Объяснение:
-F: - использовать : в качестве полевого сепаратора
NR==FNR - первый файл (текущий номер строки = общее число строк)
a[$1,$2] - Сенсорный массив на первых двух полей next - двигаться дальше на следующую строку, поэтому нам не нужно проверять альтернативное состояние NR != FNR
!(($1,$2) in a) - проверьте, была ли комбинация видна. Если нет, напечатайте линию (действие по умолчанию)

+0

Не работает для меня '(awk -W версия: GNU Awk 3.1.8 Copyright © 1998, 1991-2010 Фонд свободного программного обеспечения.) ': выводит 7 строк .. –

+0

Работает на mac/bsd awk, я проверяю, но пытаюсь заменить '$ 1, $ 2' на' $ 1 ': «$ 2» на оба места. – Kevin

+0

Также работает над 'mawk', по умолчанию awk на сервере ubuntu 13.04 – Kevin

1

Предполагаете, вы имеете в виду awk. Это можно сделать, но это будет есть 2 раза больше файлов размеров памяти:

cat file1 file2 | 
awk '{ s = substr($0, 1, 38); str[NR] = s; ex[s]++; } 
END { 
     for (i = 1; i <= NR; i++) { 
      s = str[i]; 
      if (ex[s] == 1) 
      print s; 
     } 
}' 

Выход:

cf03189f5b05eb1a9658f80d7a0e9f02:_#.g} 
5701aa8e2aa7e1cfd16ca4076bd1732a:@AQ1z 
7a1e6090568e076c55df9dc7abf356c6:[email protected] 
04046da33706518d9b15a38bcddb448e:!DFPk 
2

Код для GNU :

sed -r 'sµ(.*):.*$µ\\§\1§dµ' file2 |sed -f - file1 

Из-за многих «уродливые» символы, код для информации только, не используется в производстве.

1

В Perl'е

perl -F: -ane'BEGIN{$f=$ARGV[0]}print if$ARGV ne$f&&!$h{$F[0]};$h{$F[0]}=1' file2 file1