Ce script permet de modifier (permuter ou
ôter) les colonnes d'un
fichier. Il fonctionne avec les fichiers qui ont des colonne
formater (ayant des
colonnes
d'égales nombre de caractères) mais aussi avec des
colonnes pas formater.
Dans ce second cas il effectue le trie suivant les blancs qui
séparent les colonnes,
Troisième cas: Il peut aussi définir des colonnes suivant
le nombre de caractères que vous lui donnerai, je pense
faire aussi une autre option permettant d'entrer un motif,
permettant de couper les colonnes. Il est très pratique.
Il accepte plusieurs options et le nom du fichier à traiter en
guise d'argument. Le fichier de sortie aussi, pour plus d'ample info
sur ce script, lire
la doc à la fin
du script. Je me le suis fait pour travailler des gros fichier
(dictionnaires de traduction anglais-français et il tiens la
route sur des colonnes de plusieurs dizaines de milliers
d'enregistrement).
le script ici et la page
d'explication ici
(chmod +x colzat.pl
)):#!/usr/bin/perl -w
# remd: colzat est un script écrit pour modifier des listes, du
texte. *
# Il envisagera le fichier à modifier comme si c'etait une liste
formatée. *
# Deux options pour séléctionner soit de
caractères soit des mots: (-c et -m) *
#
--------------------
*
# Usage: colzat [-c|m] [n|n-n[1-9]] [source]
[cible|-cible]
*
#
*
# -c pour caractère,
séléctionnera n caractère sur chaque ligne,
créant *
# virtuellement
une colone sur chaque ligne qu'il déplacera (par def) *
# à la fin
de chaque ligne vers un fichier cible (voir 3éme argument).*
# Ou carrement
dans le fichier d'echantillon (f-sup) si vous l'avez *
# demander dans
la ligne de commande. Vous pouvez aussi créer
une *
# fourchette,
exemple: 3-8 qui séléctionnera du 3éme car au
8éme car. *
#
*
# -m pour mot,
séléctionnera n mot sur chaque ligne, même principe
qu'au *
# dessus. Les
mots sont calculés en fonction des espaces.Il peut aussi*
# en
plaçant deux chiffres entre un tiré, faire une
sélection du mot n*
# au mot n (voir
au
dessous).
*
#
*
# n pour chiffre, si un seul
chiffre est entrer comme argument, en tant *
# que -c
(caractère) ou -m (mot), la sélection
s'éfféctuera depuis le *
# debut de la
ligne. Pour une sélection à l'interieur de la ligne
il *
# faudra indiquer
le chiffre du debut de la sélection suivi d'un tiret*
# suivi du
chiffre de fin de sélection (sans espace entre). Exemple: *
#
2-4 # qui créera la
colone comprise entre le 2éme et le 4éme.*
# La ligne
demarre au 1er mot et donc pas a zero, pour pas ce tromper *
# pensez à
ajouter mentalement éme, donc 2-4 = 2éme au
4éme
*
#
*
# source qui indique le fichier à traiter. Entrer le
chemin complet si il ne *
# se trouve pas
dans le répertoire
courant.
*
#
*
# cible qui sera créé et recevra les
modifications faites au fichier source.*
# C-a-d: la
selection sera placer en fin de ligne.
Exemple: *
# (avec la commande: colzat.pl -m 3-5
list.txt
slist.txt
*
# le texte de
list.txt:
*
#
je
suis fou du chocolat
lanvin
*
#
tu
as un bon systeme
linux
*
# ce transformera
sur slist (la cible)
en:
*
#
je
suis Lanvin fou de
chocolat
*
#
tu
as linux un bon
systeme
*
# Par mesure de
prudence, le fichier source reste
inchangé.
*
#
*
# -cible pour créé un fichier qui ne recevra
que la selection, pour ceux qui *
# ne veulent que
la colonne voulue ou en vue de faire d'autres modifs.*
# Exemple sur la
commande: colzat.pl -m 3-5 list.txt
-slist *
# le fichier
-cible(-slist.txt) recevra (du même fichier
list.txt) *
#
fou
du
chocolat
*
# un bon
systeme
*
# Le fait de
placer un tiret devant le nom de la cible fait qu'il ne *
# recoit que la
selection.
*
#------------------------------------------------------------------------------*
# En gros j'ai écrit ce script pour palier au contrôle
déjà present sur les *
# éditeurs, il permet de prendre ou bouger des colonnes et de
les faire passer *
# de devant à derrière. Ou juste de sélectionner
les colonnes que l'on à besoin*
# J'éspère que vous comprendrai ce qu'il peut faire (je
sais je suis pas clair)*
# et qu'il vous servira autant qu'il me sert. Il fonctionne
bien.
*
# écrit par Alain Adelmar le 21 avril 2010 à Pessac 33600
Gironde France *
#------------------------------------------------------------------------------*
$ID$
use strict;
# use warnings;
use Cwd;
my $dir= cwd;
# traitement du temps pour date et heure en français
(my $sec,my $min,my $heure,my $mjour,my $mois,my $annee,my $sjour,my
$ajour,my $isdst) = localtime(time);
my @lssjour = qw( Dim Lun Mar Mer Jeu Ven Sam);
my @lssmois = qw ( Janvier Fevrier Mars Avril Mai Juin Juillet Aout
Septembre Octobre Novembre Decembre );
my $french_date_now = "$lssjour[$sjour] $mjour $lssmois[$mois] " .
($annee+=1900) . " - $heure:$min:$sec";
my $lx = "x" x 20;
my $argv = my $argm = my $file = my $fout = my $resp = my $f_sup = my
$rootfile = my $pathf = "";
my $moi = "alain Adelmar";
my $recap_lbl= "$0 écrit par $moi \nle 21 Avril 2010\nexecuter
le $french_date_now\n";
my $mode = "change";
my $datenum = my $deb = my $fin = my $k = my $u = my $args = 0;
my @primcol = my @sel = my @reste = my @nwcontenu = my @car = my @mot =
my @ls_argv = "";
my $lsel = my $lreste = my $lprimcol = my $nl = "";
print "$lx\n$recap_lbl";
# pour l'adressage/les systeme UNIX, Linux, cygwin ou autre (/) et ceux
de M$ (\)
my @gnul = ( "\\", "\/"); #pas mal because $gnul[$gnus]
sera toujours bon, je suis trop fort
my $gnus = 0;
my $cong= "this is a real gnu OS, congratulation\n";
if ($^O =~ /[msys|cygwin|linux]$/) {
$gnus++;
print "$cong";
}
elsif ($dir =~ /\//) {
$gnus++;
print "$cong";
}
else {
print "Vous etes sur une machine Petite et Molle (MicroSoft),
beuuurk...\n";
print "enfin quoi, sur un OS de merde\n";
print "gnus ne vaut que $gnus, et en plus, vos fichiers sont du
style:\n";
print "C:" . "$gnul[$gnus]" . "caca" . "$gnul[$gnus]boudin au
lieu de /super/extra\n os: $^O \n";
print "Mais $0 fonctionnera tout de meme sur cette grosse chiote
de systeme\n";
}
my $slash = $gnul[$gnus];
#----------------- sortie formatée pour l'affichage
fichiers/sorti ---------
format STDOUT_TOP =
Page @<<
$%
n
ligne
=== ===========================================================
.
# traitement arguments - fichier a traiter et verif validité
if (@ARGV) {
@ls_argv = "@ARGV";
if ($ARGV[0] =~ /^-/) {
$ARGV[0] =~ s/-(\w+)/$1/;
$argm = $ARGV[0]; # assigne $argv
# ($argv = "b") if ($ARGV[0]=~ /^b/); #
pour b pour binaire
# ($argv = "u") if ($ARGV[0]=~ /^u/); #
pour usage
# ($argv = "l") if ($ARGV[0]=~ /^l/); #
pour latin1 => utf8
# ($argv = "o") if ($ARGV[0]=~ /^o/); #
pour output (c.a.d: fichier differant)
}
else {
&use_and_expl;
print "Ici il manque le mode de sélection -c
ou -m (par caracteres ou par mots), par defaut c'est le nombre de
caractère(s)\n";
}
if($ARGV[1] =~ /^\d/) {
# receuillir $ARGV[1]
#($deb = $1, $fin = $2)= split(/-/, $ARGV[1]);
$fin = undef;
($deb = $1, $fin = $2)= split(/-/, $ARGV[1]);
# si l'utilisateur n'a pas entrer de selection de
debut, completer son choix
if(undef $fin) {
$fin = $deb;
$deb = 0;
}
#if($ARGV[1] =~ /^\d[^-]/) {
# $argc = $ARGV[1];
# }
$file = $ARGV[2];
&veriff;
$fout = $ARGV[3];
&verif_fout;
($args++) if ($ARGV[3]=~ /^-/);
#($deb = $1, $fin = $2) if ($ARGV[1]=~
/^(\d)-(\d?)/);
}
else {
&use_and_expl;
print "Ici il manque le chiffre representant le(s)
caractère(s) permettant la selection de la colonne\n";
die "navré $!";
}
}
else {
&use_and_expl;
print "Ici il manque tout, man ./colzat\n";
}
# ouverture du fichier en lecture seule
open F, "$file" or die "ouverture de $file impossible $!";
#if ($argv =~ /b/) {
# binmode F;
#}
my @contenu = <F>;
close F || die "Fermeture de $file impossible $!";
#----------------------------ici c'est bien -------------------
my $i = 0;
$deb -= 1;
$fin -= 1;
foreach my $l(@contenu) {
chomp $l;
if($argm eq "m") {
# coupe la ligne en mots
(@mot) = split(/ /, $l);
#placer dans $1, $2 et $3 les colonnes @primcol,
@sel, @reste
&decoupeligne2mot;
$lprimcol = join("", @primcol);
$lsel = join("", @sel);
$lreste = join("", @reste);
if($args == 0) {
$nl = "$lprimcol$lreste$lsel";
push @nwcontenu, "$nl\n";
}
# sinon pousse juste la ligne dans @nwcontenu
else {
push @nwcontenu, "$lsel\n";
}
@primcol = @reste = @sel = "";
$lprimcol = $lreste = $lsel = "";
}
else {
(@car) = split(//, $l);
&decoupeligne2car;
$lprimcol = join("", @primcol);
$lsel = join("", @sel);
$lreste = join("", @reste);
if($args == 0) {
$nl = "$lprimcol$lreste$lsel";
push @nwcontenu, "$nl\n";
}
# sinon pousse juste la ligne dans @nwcontenu
else {
push @nwcontenu, "$lsel\n";
}
@primcol = @reste = @sel = "";
$lprimcol = $lreste = $lsel = "";
}
write;
$k++;
}
open FOUT, ">$fout" or die "Ouverture de $fout impossible $!";
print FOUT "$lx\n$recap_lbl\ncommande: @ls_argv\n$lx\n";
print FOUT @nwcontenu;
close FOUT || die "Fermeture de $fout impossible $!";
#--------------------------------------------------------------
# attention par mot et par car pas exactement pareil
sub decoupeligne2car {
my $i = 0;
foreach my $c(@car) {
if($i < $deb) {
push @primcol, $c;
}
elsif($i < $fin) {
push @sel, $c;
}
else {
push @reste, $c;
}
$i++;
}
}
sub decoupeligne2mot {
my $i = 0;
foreach (@mot) {
if($i < $deb) {
push @primcol, "$mot[$i] ";
}
elsif($i < $fin) {
push @sel, "$mot[$i] ";
}
else {
push @reste, "$mot[$i] ";
}
$i++;
}
}
sub veriff {
unless (-f $file) {
print "Donner le nom du fichier ou vous desirez
selectionner une colone\n";
chomp($file = <STDIN>);
if (-f $file) {
print "ok pour $file on continu\n";
}
else {
print "pas possible $file n est pas un
nom de fichier valide\n";
die "desole il faut refaire, avec les
bonnes valeurs\n";
}
}
if ($file !~ /$slash/) {
$rootfile = $file;
$file = "$dir$slash$file";
}
else {
$rootfile = $file;
(my @pathf) = split("$slash", $rootfile);
$rootfile = pop @pathf;
}
while (!(-f $file)) {
print "Veuillez entrer un nom de fichier, et son
path si ailleur que dans le $dir:\n";
chomp ($file = <STDIN>);
}
my $fr_date_file = &datefile($mode);
print "info sur fichier source: $file\t$fr_date_file\n";
}
sub datefile {
($mode = 8) if ($mode=~ /^a/);
($mode = 9) if ($mode=~ /^m/);
($mode = 10) if ($mode=~ /^c/);
#print "mode vaut : $mode\n";
$datenum = ((stat($file))[$mode]);
#print "$datenum\n";
(my $sec,my $min,my $heure,my $mjour,my $mois,my $annee,my
$sjour,my $ajour,my $isdst) = (localtime($datenum));
my $fr_date_file = "$lssjour[$sjour] $mjour $lssmois[$mois] " .
($annee+=1900) . " - $heure:$min:$sec";
return $fr_date_file;
}
sub use_and_expl {
print "$lx\nUsage: colzat.pl [-cm] [source] [cible|-f_sub]\n" .
"exemple: colzat.pl -c 8 /home/alain/ma_liste.csv
-col1_ls.txt\nou\n" .
"\tcolzat.pl -m 2-4 ma_liste.csv
sortie_ma_liste.csv\n$lx\n\n";
}
sub verif_fout {
if ($fout eq "") {
if ($args == 0) {
print "Donner un nom au fichier de
sortie ou taper juste sur [Enter]\n" .
"pour avoir un nom par defaut comme:
sorti_$file\n";
}
elsif ($args >= 1) {
print "Donner un nom au fichier qui
recevra votre colonne ou taper juste sur [Enter]\n" .
"pour avoir un nom par defaut comme:
sorti_$file\n";
}
chomp($fout = <STDIN>);
if ($fout eq "") {
$fout = "$dir$slash" . "sorti$u" .
"_$rootfile";
}
}
$u= 0;
while (-e $fout) {
$u++;
$fout = "$dir$slash" . "sorti$u" . "_$rootfile";
}
print "info fichier de sortie:
$fout\t$french_date_now\n$lx\n";
}
format STDOUT =
@|||
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$k, $nl
.
#END;
1;
=head1 NOM
B<colzat.pl> -
deplace des colonnes de caractères ou de mot sur la
totalité
ou une partie d'un
fichier, du debut ou à l'interieur d'une ligne vers la fin
de la ligne ou dans un
fichier I<f-sup>.
=head1 SYNTAXE
B<colzat.pl>
[B<-cm>] [B<n>|B<n-n>] [F<source>]
[B<->F<cible>÷]
par defaut:
B<colzat.pl>
[B<n>] [F<source>]
=head1 DESCRIPTION
Ce script
E<à> pour vocation de deplacer une colonne de
caracteres,
du debut de chaque
ligne vers la fin de chaque ligne (B<n> represantant le
nombre de caracteres
formant la largeur de la colonne). Il peut le faire
egalement (avec
l'option n-n) du caractere n au caractere n.
Par défaut c'est
le nombre de caracteres qui definit sa largeur, mais il
lui est possible avec
l'option B<-m> de le faire avec des mots, comme pour
les caracteres, il
pourra selectionner la colonne soit depuis le debut de
la ligne (par defaut)
soit avec B<n-n> du B<n>ieme mot au B<n>ieme mot.
Le fichier de sortie
recevra la modification (ce script ne touche pas au
fichier source par
mesure de securite). Si vous ne desirez recevoir que la
colonne selectionner
placer simplement un tiret devant le nom du fichier
cible/sortie.
=head1 OPTIONS
-c pour
caracteres, qui est facultatif car par defaut c'est le nombre de
caracteres qui est applique.
-m pour mot, donc
le chiffre ou les chiffres separé d'un tiret represen-
terons le nombre de mot de la colonne selectionnee. (la selection de
mot ce fait par un eclatement de la ligne par les espaces).
I<Donc eviter les textes ou listes commençant par des
espaces>.
n n-n Un seul
chiffre represente une selection depuis le debut de la
ligne, deux chiffre séparer d'un tiret (sans espace) represente
une
selection du nieme car ou mot au nieme car ou mot.
source Nom du
fichier ou vous desirer faire une selection. nom complet
si pas de le repertoire courant.
cible Nom du
fichier ou vous désirez recevoir la modification. Comme
pour le source indiquer le nom complet si en dehors du repertoire
courrant. C'est le fichier de sortie.
-cible idem mais le
pêtit tiret devant signifi qu'il ne veut que la
selection et pas le reste du texte.
=item Exemple:
pour un texte de ce type:
je suis fou du chocolat Lanvin
tu as un bon systeme Linux
donnera avec la commande: colzat.pl -m 3-5 list.txt sortie_ls.log
je suis Lanvin fou du chocolat
tu as Linux un bon système
=head1 AUTEUR
Adelmar Alain
6 rue de Tunis, 33600 Pessac
email: aadelmar@numericable.fr
http://perso.numericable.fr/aadelmar/
num de version: 1.2
fait le: Mardi 22 Juin 2010
=cut