2010-06-22 15 views
1

Je travaille sur # énormes # fichiers texte (de 100mb à 1gb), je dois les analyser pour extraire des données particulaires. Le plus ennuyeux est que les fichiers n'ont pas de séparateur clairement défini.Séparateur incertain, analyse d'un journal désordonné avec sed

Par exemple:

"element" 123124 16758 "12.4" "element" "element with white spaces inside" "element" 

Je dois supprimer les espaces blancs dans les chaînes limitées par "(citation), le problème est que je ne dois pas effacer les espaces blancs « en dehors » les citations (sinon quelques chiffres fusionnerait) Je ne peux pas trouver une solution décente sed, quelqu'un peut-il m'aider avec cela?

Répondre

3

vous utilisez awk, pas sed. Et il n'y a certainement pas besoin de créer votre propre programme C, car awk est déjà un excellent programme C pour le traitement de fichiers, même sur des fichiers GB. Donc, voici un seul paquebot pour faire le travail.

$ more file 
"element" 123124 16758 "12.4" "element" "element with white spaces inside" "element" 

$ awk -F'"' '{for(i=2;i<=NF;i+=2) {gsub(/ +/,"",$i)}}1' OFS='"' file 
"element" 123124 16758 "12.4" "element" "elementwithwhitespacesinside" "element" 
+0

Cela a résolu mon problème. Juste une dernière demande, pouvez-vous s'il vous plaît m'expliquer le code? Merci beaucoup (je ne suis pas familier avec awk) – Abaco

+0

en définissant des guillemets doubles comme séparateur de champ, ces mots à l'intérieur des citations ont des numéros de champ qui sont pairs. Donc le compteur 'i' augmente de 2.' gsub() 'remplace tous les espaces par null. SVP lire le manuel gawk (recherche GNU awk) pour plus d'infos – ghostdog74

+0

+1 solution très astucieuse. –

1

Je ne peux pas trouver une solution sed, mais vous feriez mieux de simplement écrire une petite application à faire

#include <iostream> 
#include <string> 
using namespace std; 

int main() { 
    string line; 
    while(getline(cin,line)) { 
     bool inquot = false; 
     for(string::iterator i = line.begin(); i != line.end(); i++) { 
      char c = *i; 
      if (c == '"') inquot = !inquot; 

      if (c != ' ' || !inquot) cout << c; 
     } 
     cout << endl; 
    } 
    return 0; 
} 

Ensuite, allez

./a.out <test.log> new.out

AVERTISSEMENT

Cela complètement étouffer si vous avez échappé à des citations sur des lignes ou des choses multilignes entre guillemets.

Par exemple "The word \"word\" is weird" et les choses à cet effet causera des problèmes

1

Comme Jamie, je ne pense pas sed est bon pour le travail. Il se pourrait que ma compétence de sed ne soit pas assez bonne pour le travail. Voici une solution qui essentiellement la même que Jamie, mais en Python:

#!/usr/bin/env python 

# Script to delete spaces within the double quotes, but not outside. 

QUOTE = '"' 
SPACE = ' ' 

file = open('data', 'r') 
for line in file: 
    line = line.rstrip('\r\n') 
    newline = '' 
    inside_quote = False 
    for char in list(line): 
     if char == QUOTE: 
      inside_quote = not inside_quote 
     if not (char == SPACE and inside_quote): 
      newline += char 
    print(newline) 
file.close() 

Enregistrer ce script dans un fichier, par exemple rmspaces.py. Vous pouvez ensuite appeler le script à partir de la ligne de commande:

python rmspaces.py 

Notez que le script suppose que les données sont dans un fichier appelé données. Vous pouvez modifier le script au goût.