web-dev-qa-db-fra.com

Perl - pendant la gestion des fichiers (<>)

Un programme simple avec while( <> ) gère les fichiers donnés en arguments (./program 1.file 2.file 3.file) et entrée standard des systèmes Unix.

Je pense que cela les concatène dans un seul fichier et le travail est ligne par ligne. Le problème est, comment puis-je savoir que je travaille avec le premier fichier? Et puis avec le second.

Pour un exemple simple, je souhaite imprimer le contenu du fichier sur une seule ligne.

while( <> ){
    print "\n" if (it's the second file already);
    print $_;
}
18
Mantas Marcinkus

L'opérateur diamant ne concatène pas les fichiers, il les ouvre et les lit consécutivement. La façon dont vous contrôlez cela dépend de la façon dont vous en avez besoin. Un moyen simple de vérifier quand nous avons lu la dernière ligne d'un fichier est d'utiliser eof:

while (<>) {
    chomp;             # remove newline
    print;             # print the line
    print "\n" if eof; # at end of file, print a newline
}

Vous pouvez également envisager un compteur pour garder une trace du fichier dans l'ordre que vous traitez

$counter++ if eof;

Notez que ce nombre augmentera de un à la dernière ligne du fichier, donc ne l'utilisez pas prématurément.

Si vous souhaitez garder une trace du numéro de ligne $. dans le descripteur de fichier actuel, vous pouvez close le descripteur de fichier ARGV pour réinitialiser ce compteur:

while (<>) {
    print "line $. : ", $_;
    close ARGV if eof;
}
21
TLP

Le <> Est un cas particulier de l'opérateur readline. Il faut généralement un descripteur de fichier: <$fh>.

Si le descripteur de fichier est omis, le descripteur de fichier magique ARGV est utilisé.

Si aucun argument de ligne de commande n'est donné, alors ARGV est STDIN. Si des arguments de ligne de commande sont fournis, alors ARGV sera opened à chacun d'eux à tour de rôle. Ceci est similaire à

# Pseudocode
while ($ARGV = shift @ARGV) {
  open ARGV, $ARGV or do{
    warn "Can't open $ARGV: $!";
    next;
  };
  while (<ARGV>) {
    ...; # your code
  }
}

La variable $ARGV Est réelle et contient le nom de fichier du fichier actuellement ouvert.

Veuillez noter que la forme à deux arguments de open (qui est probablement utilisée ici en arrière-plan), est assez dangereuse. Le nom de fichier rm -rf * | Peut ne pas faire ce que vous voulez.

12
amon

Le nom du fichier actuel pour <> Est contenu dans le spécial $ARGVvariable .

Vous pouvez faire une correspondance croisée entre votre liste de fichiers du tableau de paramètres @ARGV Et le nom du fichier actuel pour obtenir la position du fichier dans la liste. En supposant que les seuls paramètres que vous attendez soient des noms de fichiers, vous pouvez simplement faire:

my %filename_positions = map { ( $ARGV[$_] => $_ ) } 0..$#ARGV;

while (<>) {
    my $file_number = $filename_positions{$ARGV};
    #... if ($file_number == 0) { #first file     
}
1
DVK