|
|
|
|
Bonjour,
Je voudrais savoir s'il est possible avec sed (ou awk ou sort) de trier un fichier (selon divers critères de tri) contenant plusieurs lignes représentant chacune un fichier.
Par exemple, prenons le fichier cosmos.txt (obtenu avec ls -gGt) qui contient les lignes suivantes :
total 31664
-rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
-rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
-rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
-rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
-rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
-rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg
Premierement, il faudrait eliminer la premiere ligne (total 31664). Ca devrait pas poser de problemes avec : sed '1d'
Dans mon fichier, j'ai 6 champs.
Je voudrais trier mon fichier selon le sixieme champ, soit le nom des fichiers.
De plus, je voudrais que le premier critère de tri soit le premier nombre (plus petit) associé à la résolution (compris entre [ et x ).
Le deuxième critère serait ensuite le second nombre associé à la résolution (compris entre x et ] ).
Mon dernier critère serait ensuite l'année (compris entre ] et . ).
Le résultat final désiré est le suivant :
-rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
-rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
-rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg
-rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
-rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
-rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
C'est ca mon petit probleme ... Ca me serait tres utile de trier mes fichiers selon les criteres de mon choix. Ici, j'en ai mis trois. Mais ca pourrait etre deux, cinq, etc...
Merci beaucoup,
Configuration: Linux Konqueror 3.5
Salut lami20j,
|
Salut,
|
Je viens de faire man perl et effectivement Perl est bien installe aur ma machine. Il donne des sites a la fin.
|
Ici la documentation en français http://perl.enstimac.fr/
#!/usr/bin/perl
#
while(<DATA>){
s/ /=/g;
s/\[/;/g;
s/\]/,/g;
s/(\d+)x(\d+)/$1#$2/g;
push @nontrie,$_;
}
@trie = map {$_->[0] }
sort {
$a->[0] <=> $b->[0]
||
$a->[1] <=> $b->[1]
||
$a->[2] cmp $b->[2]
} map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;
map { s/=/ /g;s/;/[/g;s/,/]/g;s/#/x/g; } @trie;
print @trie;
__END__
-rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg
-rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg
-rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg
-rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg
-rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg
-rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg
voici le résultatlami20j@debian:~/trash$ perl artagon -rwxrwx--- 1 53460 2007-10-07 02:29 600px-V838_Mon_HST[600x600]1999.jpg -rwxrwx--- 1 37021 2007-10-07 02:26 NGC2080[600x601]1998.jpg -rwxrwx--- 1 88098 2007-10-07 02:24 600px-ESO97-13[600x601]1999.jpg -rwxrwx--- 1 138525 2007-10-07 02:25 603px-Crab_Nebula[603x600]1997.jpg -rwxrwx--- 1 69991 2007-10-07 02:27 739px-Omega_Nebula[739x600]1996.jpg -rwxrwx--- 1 525752 2007-10-07 02:24 ESO97-13[1280x1280]1999.jpg lami20j |
Donc, tu as reussi a trie les lignes!
|
Donc, tu as reussi a trie les lignes!
sudo aptitude install perl-doclami20j |
Salut lami20j,
|
Salut lami20j,
|
Re,
#!/usr/bin/perl
#
while(<>){
s/ /=/g;
s/\[/;/g;
s/\]/,/g;
s/(\d+)x(\d+)/$1#$2/g;
push @nontrie,$_;
}
@trie = map {$_->[0] }
sort {
$a->[0] <=> $b->[0]
||
$a->[1] <=> $b->[1]
||
$a->[2] cmp $b->[2]
} map { [ $_, (split /[=;,#]/)[6..8] ] } @nontrie;
map { s/=/ /g;s/;/[/g;s/,/]/g;s/#/x/g; } @trie;
print @trie;
__END__ Maintenant tu peux exécuter avec ta commande.
A savoir que le problème c'est a cause du nombre de champs. J'ai l'impression que tu n'as pas toujours le même nombre de champs par ligne, il faut trouver un moyen d'avoir le même nombre de colonnes (le même nombre de séparateurs) pour chaque ligne. Ca j'ai remarqué quand j'ai fait les tests. lami20j |
Lami20j, je ne suis pas sur de te bien te comprendre ici.
|
C'est très rare quand j'écrit un code de la même façon.
#!/usr/bin/perl
while(<DATA>){
/.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
chomp;
push @nontrie,[$_,$2,$3,$4];
}
@trie = map {$_->[0] }
sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
||
$a->[3] <=> $b->[3]
} @nontrie;
print "$_\n" for @trie;
__END__
2. pour tester avec la commande ls -gG * | perl tri.pl utilise ce script tu remarqueras qu'au lieu de <DATA> j'utilise l'opérateur <> sans rien à l'intérieur (cet opérateur s'appelle opérateur diamant ;-) à cause de la forme (en fait Larry Wall ne trouvait pas un nom pour cet opérateur et c'est sa petite fille qui a dit "it's like a diamant - voilà pour la petite histoire ;-) #!/usr/bin/perl
while(<>){
/.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
chomp;
push @nontrie,[$_,$2,$3,$4];
}
@trie = map {$_->[0] }
sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
||
$a->[3] <=> $b->[3]
} @nontrie;
print "$_\n" for @trie;
__END__
lami20j |
Bonjour lami20j,
|
Salut,
#!/usr/bin/perl
while(<DATA>){
/.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
chomp;
push @nontrie,[$_,$2,$3,$4];
}
@trie = map {$_->[0]}
sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
||
$a->[3] <=> $b->[3]
}
map { $_ } @nontrie;
print "$_\n" for @trie;
pour la ligne de commande enlève DATA
Et voici la répresentation visible L'algorithme s'exécute dans l'ordre inverse comme tu l'as bien remarqué Etape 1 - pas vraiement necessaire toutefois pour mettre en evidence l'algorithme de Randal Scwartz appellé map-sort-map Le tableau @nontrie contient plusieurs tableau anonymes dont 4 champs chacun 1er champ c'est la ligne obtenu avec ls 2,3 et 4 sont les critères de tri @tmp = map { $_ } @nontrie; # chaque élément de @nontrie c'est un tableau anonymeEtape2
Ici le table @tmp est trié selon 3 critère 2 , 3 et 4 ème champ (ce que tu as demandé) En fait ce sont tes 3 champs, mais en 1ère position j'ai ajouté la ligne obtenu avec ls pour pouvoir l'afficher en fonction de tri @tmp_trie = sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
||
$a->[3] <=> $b->[3]
} @tmp;Etape3
Il nous reste à extraire du tableau trié seulement le 1er champ (la ligne obtenu avec ls) @trie = map { $_->[0] } @tmp_trie;
lami20j |
lami20j,
|
Essaie celui ci en ligne de comamnde #!/usr/bin/perl
while(<>){
/.*:\d+\s+(.*)\[(\d+)x(\d+)\](\d{4})\..*/;
chomp;
push @nontrie,[$_,$2,$3,$4];
}
@trie = map {$_->[0]}
sort {
$a->[1] <=> $b->[1]
||
$a->[2] <=> $b->[2]
||
$a->[3] <=> $b->[3]
}
map { $_ } @nontrie;
print "$_\n" for reverse @trie;
lami20j |