2010-10-13 17 views
1

Je fichier quelque chose comme çaTransposer un fichier dans unix

1111,K1 
2222,L2 
3333,LT50 
4444,K2 
1111,LT50 
5555,IA 
6666,NA 
1111,NA 
2222,LT10 

sortie qui est nécessaire

1111,K1,LT50,NA 
2222,L2,LT10 
3333,LT50 
4444,K2 
5555,IA 
6666,NA 

1 er numéro de colonne peut répéter à tout moment, mais la sortie que j'ai besoin est sort et uniq

+1

Pourquoi dire "transposer"? – Wok

+1

Comment cela est-il lié aux tests unitaires? Un hachage de clé pour la liste peut être rempli en un seul passage, puis itérer sur le hachage pour obtenir la sortie dont vous avez besoin. – Gishu

+0

Vous voulez probablement écrire un script simple dans un langage avec des hachages et un support regex, par ex. Perl. –

Répondre

2

Voici une tentative compréhensible à l'aide d'un outil non standard, shell SQLite. La base de données est en mémoire.

echo 'create table tmp (a int, b text); 
     .separator , 
     .import file.txt tmp 
     .output out.txt 
     SELECT a, group_concat(b) FROM tmp GROUP BY a ORDER BY a ASC; 
     .output stdout 
     .q' | sqlite 
5
awk -F"," '{a[$1]=a[$1]FS$2}END{for(i in a) print i,a[i]}' file | sort 

Si vous avez un gros fichier, vous pouvez essayer d'imprimer les articles sur toutes les quelques lignes, par exemple 50000

BEGIN{FS=","} 
{ a[$1]=a[$1]FS$2 } 
NR%50000==0 { 
    for(i in a) { print a[i] } 
    delete a #delete array so it won't take up memory 
} 
END{ 
    for(i in a){ print a[i] } 
} 
+0

'| sort' a été demandé aussi – Unreason

+0

ghostdog74 Merci pour votre réponse .. votre script fonctionne très bien. mais j'ai un problème, j'ai fichier plus de 20Lakhs Rows .. Pour la boucle que vous avez utilisé peut prendre beaucoup de temps. vous avez des suggestions pour cela. – gyrous

+0

qu'est ce que 20Lakhs lignes? awk est un outil de traitement de texte assez rapide. Je doute fortement que ce soit lent pour votre problème. – ghostdog74

1

Cette solution est en python. Le script lit les données de stdin.

#!/usr/bin/env python 
import sys 
d = {} 
for line in sys.stdin.readlines(): 
    pair = line.strip().split(',') 
    d[pair[0]] = d.get(pair[0], []) 
    d[pair[0]].append(str(pair[1])) 
for key in sorted(d): 
    print "%s,%s" % (key, ','.join(d[key])) 
0

Voici un en Perl, mais il ne va pas être particulièrement efficace:

#!/usr/bin/perl -w 
use strict; 
my %lines; 
while (<>) { 
    chomp; 
    my ($key, $value) = split /,/; 
    $lines{$key} .= "," if $lines{$key}; 
    $lines{$key} .= $value; 
} 

my $key; 
for $key in (keys(%lines)) { 
    print "$key,$lines{$key}\n"; 
} 

Utilisez comme ceci:

$ ./command <file >newfile 

Vous aurez probablement plus de chance avec un multiple solution de passe, cependant. Je n'ai pas vraiment le temps d'écrire ça pour toi. Voici un aperçu:

  1. Saisissez et supprimez la première ligne du fichier.
  2. Analyser le reste du fichier, en concaténant la ligne correspondante et en l'enlevant.
  3. À la fin du fichier, affichez votre nouvelle ligne longue.
  4. Si le fichier contient toujours du contenu, reboucler à 1.