2017-09-26 7 views
3

Désolé pour une question stupide, mais je suis un débutant, donc je ne peux pas résoudre ce problème.

Je travaille avec des fichiers où des blocs de données sont divisés par des lignes de = signes de longueur différente, suivis de \n. Je veux lire ces blocs comme des enregistrements distincts, en utilisant $/ = "=+\n"; Mais il ne détecte pas le séparateur ===.

donc mon code est:

$ cat prog1 
#!/usr/bin/perl 

use v5.22; 
use strict; 
use warnings; 

$/ = "=+\n"; 
$\="+++\n"; 

while (<>){ 
    chomp; 
    print; 
} 

Mes données:

$ cat data1 
line1 
line2 
=== 
line4 
line5 

Ma sortie:

$ ./prog1 data1 
line1 
line2 
=== 
line4 
line5 
+++ 
+1

[Q & A] (https://stackoverflow.com/q/19159052/133939) – Zaid

+0

Merci! C'est exactement ce que je voulais savoir, je vais lire le A. –

Répondre

5

$/ ne prend pas en charge les expressions régulières. Vous devrez utiliser ===\n.

Vous pouvez cependant utiliser une regex pour pseudo chomp en utilisant une regex.

#!/usr/bin/env perl 
use strict; 
use warnings; 


$/ = "=\n"; 
$\="+++\n"; 

while (<>){ 
    s/^=+\n\z//gm; 
    print; 
} 

Voir: perlvar:

la valeur de/$ est une chaîne, pas une expression régulière.

+0

Merci! C'est dommage, je suppose que ça marcherait comme dans awk. Probablement, il serait plus facile de lire le fichier entier dans une variable, puis de le diviser en utilisant '" = + \ n "' comme séparateur. –

+1

@evb dépend de la taille du fichier. – simbabque

+0

Vous pouvez toujours lire ligne par ligne, assembler un tampon et le 'traiter' (et l'effacer) lorsque vous frappez votre regex. Mais cette approche semblait faire ce que vous vouliez, et était plus simple. – Sobrique

2

Si le fichier est assez court, le charger en mémoire et divisée sur tout indicateur de fin de disque que vous voulez:

local $/; 
my @lines = split /=+\n|\++\n/, <>; 
foreach my $line (@lines) { ... } 

S'il est important que le séparateur d'enregistrement était (par exemple, si vous devez distinguer les enregistrements qui se terminent par ===\n des dossiers qui se terminent par +++\n), capturer le séparateur d'enregistrement

local $/; 
my @lines = split /(=+\n|\++\n)/, <>; 
while (my $line = shift @lines) { 
    my $record_separator = shift @lines; 
    ... 
}