J'ouvre le fichier en mode APPEND. Je dois remplacer les lignes 2,3 et 4 dans le fichier, puis j'ai besoin d'ajouter les nouvelles données à la fin du fichier.
Je pense que c'est le FAQ réponse que j'ai republié à Stackoverflow le plus. Le perlfaq5 a la réponse à Comment puis-je changer, supprimer, Ou insérez une ligne dans un fichier ou annoncez au début d'un fichier? .
Oubliez les trucs de mode append. Cela va juste rendre votre vie plus difficile.
L'idée de base de l'insertion, de la modification ou de la suppression d'une ligne d'un fichier texte implique la lecture et l'impression du fichier au point que vous souhaitez modifier, en effectuant la modification, puis en lisant et imprimez le reste du fichier. Perl ne fournit pas d'accès aléatoire aux lignes (en particulier depuis le séparateur d'entrée d'enregistrement, $/
, est mutable), bien que des modules tels que - TIE :: Fichier peut simuler.
Un programme PERL pour effectuer ces tâches prend la forme de base d'ouverture d'un fichier, imprimer ses lignes, puis fermez le fichier:
open my $in, '<', $file or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
while( <$in> )
{
print $out $_;
}
close $out;
Dans cette forme de base, ajoutez les pièces dont vous avez besoin pour insérer, modifier ou supprimer des lignes.
Pour préparer des lignes au début, imprimez ces lignes avant de saisir la boucle qui imprime les lignes existantes.
open my $in, '<', $file or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
print $out "# Add this line to the top\n"; # <--- HERE'S THE MAGIC
while( <$in> )
{
print $out $_;
}
close $out;
Pour modifier les lignes existantes, insérez le code pour modifier les lignes à l'intérieur de la boucle. Dans ce cas, le code trouve toutes les versions de "Perl" et les majuscules. L'arrive pour chaque ligne, alors assurez-vous que vous êtes censé faire cela sur toutes les lignes!
open my $in, '<', $file or die "Can't read old file: $!";
open my $out, '>', "$file.new" or die "Can't write new file: $!";
print $out "# Add this line to the top\n";
while( <$in> )
{
s/\b(Perl)\b/Perl/g;
print $out $_;
}
close $out;
Pour ne changer qu'une ligne particulière, le numéro de ligne d'entrée, $.
, est utile. D'abord lire et imprimer les lignes jusqu'à celui que vous souhaitez modifier. Ensuite, lisez la ligne unique que vous souhaitez modifier, le changer et l'imprimer. Après cela, lisez le reste des lignes et imprimez ceux-ci:
while( <$in> ) # print the lines before the change
{
print $out $_;
last if $. == 4; # line number before change
}
my $line = <$in>;
$line =~ s/\b(Perl)\b/Perl/g;
print $out $line;
while( <$in> ) # print the rest of the lines
{
print $out $_;
}
Pour sauter des lignes, utilisez les commandes de bouclage. Le suivant dans cet exemple passe des lignes de commentaire et la dernière cesse de tout traitement une fois qu'elle rencontre soit __END__
ou __DATA__
.
while( <$in> )
{
next if /^\s+#/; # skip comment lines
last if /^__(END|DATA)__$/; # stop at end of code marker
print $out $_;
}
Faites le même genre de chose pour supprimer une ligne particulière en utilisant Suivant pour sauter les lignes que vous ne souhaitez pas apparaître dans la sortie. Cet exemple saute toutes les cinquième ligne:
while( <$in> )
{
next unless $. % 5;
print $out $_;
}
Si, pour une raison quelconque, vous voulez vraiment voir le fichier entier à la fois plutôt que de traiter la ligne de ligne, vous pouvez le réduire (aussi longtemps que vous pouvez vous adapter au tout en mémoire!):
open my $in, '<', $file or die "Can't read old file: $!"
open my $out, '>', "$file.new" or die "Can't write new file: $!";
my @lines = do { local $/; <$in> }; # Slurp!
# do your magic here
print $out @lines;
Des modules tels que Fichier :: slurp et Cravate :: Fichier peut aider à cela aussi. Si vous le pouvez, évitez toutefois de lire l'ensemble du fichier à la fois. Perl ne donnera pas cette mémoire au système d'exploitation jusqu'à ce que le processus finisse.
Vous pouvez également utiliser Perl One-Linders pour modifier un fichier en place. Les modifications suivantes changent 'Fred' à 'barney' dans infile.txt , écraser le fichier avec le nouveau contenu. Avec le -p
Commutateur, Perl enveloppe une boucle tandis que sur le code que vous spécifiez avec -e
, et -i
active l'édition sur place. La ligne actuelle est en $_
. Avec -p
, Perl imprime automatiquement la valeur de $_
À la fin de la boucle. Voir Perlrun pour plus de détails.
Perl -pi -e 's/Fred/Barney/' inFile.txt
Pour faire une sauvegarde d'infile.txt, donnez -i
une extension de fichier à ajouter:
Perl -pi.bak -e 's/Fred/Barney/' inFile.txt
Pour ne changer que la cinquième ligne, vous pouvez ajouter un test de test $.
, le numéro de ligne d'entrée, puis effectuer uniquement l'opération lorsque le test passe:
Perl -pi -e 's/Fred/Barney/ if $. == 5' inFile.txt
Pour ajouter des lignes avant une certaine ligne, vous pouvez ajouter une ligne (ou des lignes!) Avant que Perl imprime $_
:
Perl -pi -e 'print "Put before third line\n" if $. == 3' inFile.txt
Vous pouvez même ajouter une ligne au début d'un fichier, car la ligne actuelle est imprimée à la fin de la boucle:
Perl -pi -e 'print "Put before first line\n" if $. == 1' inFile.txt
Pour insérer une ligne après une heure déjà dans le fichier, utilisez le -n
changer. C'est juste comme -p
Sauf que cela n'imprime pas $_
À la fin de la boucle, vous devez donc le faire vous-même. Dans ce cas, impression $_
Tout d'abord, puis imprimez la ligne que vous souhaitez ajouter.
Perl -ni -e 'print; print "Put after fifth line\n" if $. == 5' inFile.txt
Pour supprimer des lignes, imprimez uniquement ceux que vous souhaitez.
Perl -ni -e 'print unless /d/' inFile.txt
... or ...
Perl -pi -e 'next unless /d/' inFile.txt
Vous pouvez le faire avec Cravate :: Fichier . (Sachez qu'il devra réécrire l'intégralité du fichier afin de remplacer les lignes initiales, mais la naissance :: Fichier cachera les détails de votre part.)
Un bon idiome Perl est de lire et d'écrire l'entrée et la sortie standard. Vous pouvez tuyer et rediriger si nécessaire. À travers l'opérateur <> (une enveloppe à readline), Perl ouvrira les fichiers que vous transmettez comme argument sur la ligne de commande.
Pour répondre à votre question, quelques lignes de code (aussi propres que possible):
#!/usr/bin/env Perl
use strict; use warnings;
while (<>) {
if ($. == 2) {
print "new data", "\n";
next;
}
if ($. == 3) {
print "very new data", "\n";
next;
}
print;
}
print "more data", "\n";
Ensuite, appelez-la de cette façon: Perl YourScript.pl entrementfile> OutputFileFile
Si vous souhaitez ouvrir les fichiers vous-même (ici, nous ignorons simplement les lignes indésirables):
my open $in_fh, '<', $inputfile
or die "Can't open file $inputfile: $!";
my open $out_fh, '>', $outputfile
or die "Can't open file $output: $!";
while (my $line = <$in_fh>) {
next if ( $. == 2 or $. == 3 or $. == 4 );
print $out_fh $line;
}
print $out_fh "...whatever\n";
Si vous ouvrez un fichier dans APPEND MODE Ensuite, vous ne pouvez pas remplacer une ligne déjà dans le fichier lorsque vous l'avez ouverte. APPEND Fichier signifie que votre programme n'a la possibilité de lire le fichier et d'ajouter à la fin de celui-ci.
Vous pouvez créer un nouveau fichier, ajouter du contenu à celui-ci (peut-être sur la base du contenu d'un fichier différent), puis copiez le nouveau fichier sur le fichier différent.
Je suppose que je ne comprends pas bien l'affectation.