Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Transformation d'un fichier texte

19 réponses
Avatar
Jean NEMAR
Bjr,


(je ne sais pas si je poste dans le bon forum,
mais je ne sais pas exactement où publier ce message ...)

Soit un fichier texte (nviron 6000 lignes) :
texte1
texte2
texte3
...

Je souhaiterais le transformer en :
texte1;texte2;texte3;...
texten;texten+1;...

Les contraintes étant :
- les lignes ne doivent pas dépasser 255 caractères ;
- les "textes" ne peuvent pas être tronqués.

Si possible, sous Windows (script, powershell).
Mais pourquoi pas en shell Unix ...

Merci de votre aide.

--
J.N.

10 réponses

1 2
Avatar
David LE BOURGEOIS
Bjr,


Bonjour.

(je ne sais pas si je poste dans le bon forum,
mais je ne sais pas exactement où publier ce message ...)

Soit un fichier texte (nviron 6000 lignes) :
texte1
texte2
texte3
...

Je souhaiterais le transformer en :
texte1;texte2;texte3;...
texten;texten+1;...

Les contraintes étant :
- les lignes ne doivent pas dépasser 255 caractères ;
- les "textes" ne peuvent pas être tronqués.

Si possible, sous Windows (script, powershell).
Mais pourquoi pas en shell Unix ...


Et pourquoi pas en awk :

$ cat transform.awk
#!/usr/bin/awk -f

BEGIN {
MAX = 30;
SEP = ";"
SEP_LEN = length(SEP);
sep = "";
line = "";
size = 0;
}

{
len = length;
if (size + len + SEP_LEN > MAX) {
printf "n%s", $0;
size = len;
} else {
printf "%s%s", sep, $0;
size += len + SEP_LEN;
}
}

NR == 1 {
sep = SEP;
}

END {
printf "n";
}


$ cat textes
texte1
texte2
texte3
texte4
texte5
texte6
texte7
texte8
texte9
texte10
texte11
texte12
texte13
texte14
texte15


$ ./transform textes
texte1;texte2;texte3;texte4
texte5;texte6;texte7;texte8
texte9;texte10;texte11;texte12
texte13;texte14;texte15

La valeur MAX est mise à 30 ici, pour l'exemple. Il suffit de la
remplacer par 255, comme voulu.

--
David LE BOURGEOIS
e-mail : david.lebourgeois (at) free.fr
jabber : david.lebourgeois (at) jabber.fr

Avatar
Jean NEMAR
David LE BOURGEOIS wrote:
Et pourquoi pas en awk :
$ cat transform.awk
(...)


ça marche. Merci beaucoup !


--
J.N.

Avatar
Fred
Dans : news:46977b50$0$27369$,
Jean NEMAR disait :
Bjr,


Bonjour,

Soit un fichier texte (nviron 6000 lignes) :
texte1
texte2
texte3
...

Je souhaiterais le transformer en :
texte1;texte2;texte3;...
texten;texten+1;...

Les contraintes étant :
- les lignes ne doivent pas dépasser 255 caractères ;
- les "textes" ne peuvent pas être tronqués.


Une façon de faire en vbscript ci-dessous.
En attendant une solution en une seule ligne par les gourous du
PowerShell :-)

Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
Const TristateUseDefault = -2 'encodage système
Const TristateTrue = -1 'Unicode
Const TristateFalse = 0 'ASCII

Set fso = CreateObject("Scripting.FileSystemObject")
Set src = fso.OpenTextFile("source.txt", ForReading, TristateUseDefault)
Set dst = fso.OpenTextFile("destination.txt", ForWriting,
TristateUseDefault)

length = 0
While Not src.AtEndOfStream
line = src.ReadLine
length = length + Len(line) + 1
If length > 255 Then
dst.WriteLine
length = Len(line) + 1
End If
dst.Write(line & ";")
Wend
dst.WriteLine
src.Close
dst.Close


--
Fred
http://www.cerber mail.com/?3kA6ftaCvT (enlever l'espace)

Avatar
Jacques Barathon [MS]
"Jean NEMAR" wrote in message
news:46977b50$0$27369$
...
Soit un fichier texte (nviron 6000 lignes) :
texte1
texte2
texte3
...

Je souhaiterais le transformer en :
texte1;texte2;texte3;...
texten;texten+1;...

Les contraintes étant :
- les lignes ne doivent pas dépasser 255 caractères ;
- les "textes" ne peuvent pas être tronqués.


Essaie le script PowerShell suivant, ça devrait donner le résultat escompté:

--- write-255.ps1 ---
param ($from)

$text = get-content $from

$buffer = $text[0]
for ($i=1; $i -lt $text.length; $i++)
{
$item = $text[$i]
if ("$buffer;$item".length -le 255)
{
$buffer = $buffer+ ";" + $item
if ($i -eq $text.length-1)
{
$buffer
}
}
else
{
$buffer
$buffer = $item
}
}
--- fin de fichier ---

Exemple d'utilisation:

PS> write-255 -from oldfile.txt > newfile.txt

Jacques

Avatar
Jacques Barathon [MS]
"Fred" wrote in message
news:
...
Une façon de faire en vbscript ci-dessous.
En attendant une solution en une seule ligne par les gourous du PowerShell
:-)


Je ne dois sans doute pas mériter le titre de gourou, car ma solution en
PowerShell n'est guère plus courte que la tienne :-)

Jacques

Avatar
Fred
Dans : news:%23P$,
Jacques Barathon [MS] disait :
"Fred" wrote in message
news:
...
Une façon de faire en vbscript ci-dessous.
En attendant une solution en une seule ligne par les gourous du
PowerShell :-)


Je ne dois sans doute pas mériter le titre de gourou, car ma solution
en PowerShell n'est guère plus courte que la tienne :-)


Oui, j'avoue être un peu déçu :-(
Une question s'impose donc : À quand gourou ?
Sur ce calembour bondissant, dont la médiocrité ne manquera pas de me
poursuivre, je sors :-)

--
Fred
http://www.cerber mail.com/?3kA6ftaCvT (enlever l'espace)


Avatar
Jean NEMAR
Bonjour,


Jacques Barathon [MS] wrote:
Essaie le script PowerShell suivant, ça devrait
donner le résultat escompté


Oui, ça marche très bien.
Cela n'a pas été sans mal car je ne connais pas du tout
PowerShell (justement, c'était pour me forcer à m'y mettre).
Cela semble très prometteur, mais j'ai du boulot !! ;-)

Merci beaucoup !


--
J.N.

Avatar
Jean NEMAR
Bonjour,


Une façon de faire en vbscript ci-dessous.


Parfait.
En plus (;-) j'ai compris et modifié un peu pour
que les lignes ne se terminent pas par ";".

Merci beaucoup !


--
J.N.

Avatar
Jacques Barathon [MS]
"Fred" wrote in message
news:
Dans : news:%23P$,
Jacques Barathon [MS] disait :
"Fred" wrote in message
news:
...
Une façon de faire en vbscript ci-dessous.
En attendant une solution en une seule ligne par les gourous du
PowerShell :-)


Je ne dois sans doute pas mériter le titre de gourou, car ma solution
en PowerShell n'est guère plus courte que la tienne :-)


Oui, j'avoue être un peu déçu :-(
Une question s'impose donc : À quand gourou ?


Bon, on est encore assez loin du vrai "one-liner" mais ça y ressemble un peu
plus que ma première version:

PS> gc oldfile.txt|%{$o=$ofs;$ofs=";";$l=0;$a=@();$e=1}{if
($l+$_.length+1 -gt 255)
{"$a";$l=0;$a=@();$e=0};$a+=$_;$l+=$_.length+1;$e=1}{if ($e)
{"$a"};$ofs=$o}>newfile.txt

Je suppose que la ligne ci-dessus va apparaître tronquée, et comme mieux
vaut prévenir que guérir: tout ce qui suit "PS>" ci-dessus doit être tapé
sur une même ligne de commande.

Cela dit, l'intérêt du compactage sur une seule ligne de commande est très
anecdotique, pour ne pas dire inexistant. Ce qui l'est moins, c'est
l'illustration - pour ceux qui prendront la peine de déchiffrer cette
ligne - de l'usage de la variable standard $OFS pour afficher les valeurs
d'un tableau avec un séparateur personnalisé.

Allez Fred, tu peux rentrer, tu vas attraper une insolation :)

Jacques



Avatar
Jacques Barathon [MS]
"Jacques Barathon [MS]" wrote in message
news:
...
Bon, on est encore assez loin du vrai "one-liner" mais ça y ressemble un
peu plus que ma première version:

PS> gc oldfile.txt|%{$o=$ofs;$ofs=";";$l=0;$a=@();$e=1}{if
($l+$_.length+1 -gt 255)
{"$a";$l=0;$a=@();$e=0};$a+=$_;$l+=$_.length+1;$e=1}{if ($e)
{"$a"};$ofs=$o}>newfile.txt


Petite amélioration, j'ai supprimé le besoin d'avoir un compteur dédié pour
la longueur de chaque ligne:

PS> gc oldfile.txt|%{$o=$ofs;$ofs=";";$a=@();$e=1}{if ("$a;$_".length -gt
255) {"$a";$a=@();$e=0};$a+=$_;$e=1}{if ($e) {"$a"};$ofs=$o}>newfile.txt

Même avertissement que précédemment: le code qui suit "PS>" ci-dessus est à
saisir sur une seule ligne.

Jacques

1 2