Mam duży plik danych dump.all.lammpstrj, którego muszę podzielić / kategoryzować w serię plików, takich jak Z_1_filename, Z_2_filename, Z_3_filename itp. Na podstawie współrzędnych każdy rekord.

Współrzędne są zapisywane w sposób nieuporządkowany, więc mój program odczytuje każdą linię i określa, który plik ten powinien zostać wysłany do.

Używam zmiennej, {x0}}

I mam nadzieję otworzyć wszystkie możliwe pliki takie jak takie

for ( my $i = 1; $i <= 100; $i++ ) {
  $filehandle = "Z_$i_DUMP";
  open $filehandle,'>', "Z_$i_dump.all.lammpstrj.dat";
  ...
}

Ale podczas prowadzenia mojego programu dostaję wiadomość

Nie można używać ciągów ("Z_90_dump") jako symbol ref, podczas gdy "ścisły refs" w użyciu w ...

Nie chcę zeskanować wszystkich danych dla każdego pliku wyjściowego, ponieważ dump.all.lammpstrj jest tak duże, że skanowanie zajmie dużo czasu.

Czy jest jakiś sposób, aby użyć zdefiniowanej zmiennej jako uchwytu pliku?

2
Leon WANG 2 czerwiec 2018, 23:28

3 odpowiedzi

Najlepsza odpowiedź

Aby dać ci pomysł na to, jak to można zrobić. Umieść uchwyty do pliku w skrócie (lub być może, jeśli są indeksowane przez numery).

use strict;
use warnings;
my %fh;                                                        #file handles
open $fh{$_}, '>', "Z_${_}_dump.all.lammpstrj.dat" for 1..100; #open 100 files
for(1..10000){                                    #write 10000 lines in 100 files
    my $random=int(1+rand(100));                  #pick random file handle
    print {$fh{$random}} "something $_\n";
}
close $fh{$_} for 1..100;
5
Kjetil S. 2 czerwiec 2018, 22:00

Nie przypisuj niczego do $filehandle lub ustaw go do undef przed połączeniem open(). Otrzymasz ten błąd, ponieważ przypisałeś ciąg do $filehandle (który w każdym razie nie ma użycia).

Zobacz także "Open" w Perldoc:

Jeśli FileHandle jest niezdefiniowaną zmienną skalarną (lub elementem macierzowym lub Hash), nowa kandura plików jest autovivified, co oznacza, że zmienna jest przypisana odniesienie do nowo przydzielonego anonimowego pliku FileHandle. W przeciwnym razie, jeśli FileHandle jest wyrażeniem, jego wartość jest prawdziwym zawieszeniem pliku. (Jest to uważane za symboliczne odniesienie, więc use strict "refs" nie powinno działać.)

Aby mieć więcej uchwytów z plików jednocześnie i wygodnie mapować je do nazw plików, należy rozważyć za pomocą hasha z nazwą pliku (lub dowolne identyfikator odpowiadającego) jako klucza, aby je przechowywać. Możesz sprawdzić, czy klucz istnieje (patrz "Istnieje") i wartość jest zdefiniowana (patrz " zdefiniowany "), aby uniknąć ponownego otwarcia pliku.

2
sticky bit 2 czerwiec 2018, 20:41

Szczerze doceniam Kjetyl S. i lepki bit. Przetestowałem to i ich sugestia działa dobrze. I zauważyłem, że istnieje inny sposób zapisywania danych do różnych plików bez zmiany FileHandler. Właściwie zmieniłem nazwy plików za pomocą tego samego obsługi plików.

....
for my $i=0;$i<=$max_number;$i++;
{
   $file="$i\_foo.dat";
   open DAT,'>>',"$file";
   ......
}
0
Leon WANG 25 czerwiec 2018, 16:01