Próbuję otworzyć plik .html jako jeden duży długi ciąg. Oto co mam:
open(FILE, 'index.html') or die "Can't read file 'filename' [$!]\n";
$document = <FILE>;
close (FILE);
print $document;
Co skutkuje w:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN
Jednak chcę, aby wynik wyglądał następująco:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
W ten sposób mogę łatwiej przeszukiwać cały dokument.
Odpowiedzi:
Dodaj:
przed odczytaniem z uchwytu pliku. Zobacz: Jak mogę wczytać cały plik naraz? lub
Zobacz Zmienne związane z uchwytami plików w
perldoc perlvar
iperldoc -f local
.Nawiasem mówiąc, jeśli możesz umieścić swój skrypt na serwerze, możesz mieć wszystkie potrzebne moduły. Zobacz Jak mogę zachować własny katalog modułów / bibliotek? .
Ponadto Ścieżka :: Klasy :: File pozwala slurp i rzygać .
Ścieżka :: Tiny daje jeszcze więcej wygody metod takich jak
slurp
,slurp_raw
,slurp_utf8
a także ichspew
odpowiedniki.źródło
$/
, prawdopodobnie powinieneś dodać linki do dalszych informacji.local
a niemy
.Zrobiłbym to tak:
Zwróć uwagę na użycie trzyargumentowej wersji open. Jest znacznie bezpieczniejszy niż stare wersje dwu- (lub jedno-) argumentowe. Zwróć również uwagę na użycie leksykalnego uchwytu pliku. Leksykalne uchwyty plików są ładniejsze niż stare warianty gołego słowa z wielu powodów. Wykorzystujemy tutaj jeden z nich: zamykają się, gdy wychodzą poza zakres.
źródło
Z plikiem :: Slurp :
Tak, nawet ty możesz używać CPAN .
źródło
Can't locate File/Slurp.pm in @INC (@INC contains: /usr/lib/perl5/5.8/msys
:(Wszystkie posty są nieco nieidiomatyczne. Idiom to:
Przeważnie nie ma potrzeby ustawiania $ / to
undef
.źródło
local $foo = undef
jest po prostu metodą sugerowaną przez Perl Best Practice (PBP). Jeśli publikujemy fragmenty kodu, myślę, że zrobienie wszystkiego, co w naszej mocy, aby było jasne, byłoby dobrą rzeczą.Z perlfaq5: Jak mogę odczytać cały plik naraz? :
Możesz użyć modułu File :: Slurp, aby zrobić to w jednym kroku.
Zwyczajowe podejście Perla do przetwarzania wszystkich wierszy w pliku polega na wykonywaniu tego po jednym wierszu na raz:
Jest to znacznie bardziej wydajne niż wczytywanie całego pliku do pamięci jako tablicy wierszy, a następnie przetwarzanie go po jednym elemencie na raz, co jest często - jeśli nie prawie zawsze - złym podejściem. Ilekroć zobaczysz, że ktoś to robi:
Powinieneś długo i intensywnie przemyśleć, dlaczego potrzebujesz wszystkiego załadowanego na raz. To po prostu nie jest skalowalne rozwiązanie. Możesz również uznać za zabawniejsze użycie standardowego modułu Tie :: File lub powiązań $ DB_RECNO modułu DB_File, które pozwalają ci powiązać tablicę z plikiem tak, że dostęp do elementu tablica faktycznie uzyskuje dostęp do odpowiedniej linii w pliku .
Możesz wczytać całą zawartość uchwytu pliku do wartości skalarnej.
To tymczasowo unieważnia twój separator rekordów i automatycznie zamyka plik przy wyjściu z bloku. Jeśli plik jest już otwarty, użyj tego:
W przypadku zwykłych plików możesz również użyć funkcji odczytu.
Trzeci argument sprawdza rozmiar bajtów danych w uchwycie pliku INPUT i wczytuje tę liczbę bajtów do bufora $ var.
źródło
Prosty sposób to:
Innym sposobem jest zmiana separatora rekordów wejściowych „$ /”. Możesz to zrobić lokalnie w czystym bloku, aby uniknąć zmiany globalnego separatora rekordów.
źródło
{local $/; open(my $f, '<', 'filename'); $d = <$f>;}
open
lub niejawnie wywołanegoclose
.my $d = do{ local $/; open(my $f, '<', 'filename') or die $!; my $tmp = <$f>; close $f or die $!; $tmp}
. (Nadal ma problem z tym, że nie określa kodowania wejściowego.)use autodie
, głównym ulepszeniem, które chciałem pokazać, był leksykalny uchwyt pliku i otwarty 3 arg. Czy jest jakiś powód, dla którego to robiszdo
? dlaczego po prostu nie wrzucić pliku do zmiennej zadeklarowanej przed blokiem?Albo zestaw
$/
doundef
(patrz odpowiedź jrockway użytkownika) lub po prostu złączyć wszystkie linie w pliku jest:Zaleca się używanie skalarów do uchwytów plików w każdej wersji Perla, która to obsługuje.
źródło
Inny możliwy sposób:
źródło
Otrzymujesz tylko pierwszą linię od operatora diamentu,
<FILE>
ponieważ oceniasz ją w kontekście skalarnym:W kontekście listy / tablicy operator rombu zwróci wszystkie wiersze pliku.
źródło
<=>
a<>
jest operatorem diamentu.Zrobiłbym to w najprostszy sposób, aby każdy mógł zrozumieć, co się dzieje, nawet jeśli są sprytniejsze sposoby:
źródło
<f>
- zwraca tablicę linii z naszego pliku (jeśli$/
ma wartość domyślną"\n"
), a następniejoin ''
umieści tę tablicę w.źródło
To bardziej sugestia, jak tego NIE robić. Po prostu ciężko mi było znaleźć błąd w dość dużej aplikacji Perla. Większość modułów miała własne pliki konfiguracyjne. Aby odczytać pliki konfiguracyjne jako całość, znalazłem gdzieś w Internecie ten pojedynczy wiersz Perla:
Ponownie przypisuje separator linii, jak wyjaśniono wcześniej. Ale również ponownie przypisuje STDIN.
Miało to co najmniej jeden efekt uboczny, którego znalezienie kosztowało mnie wiele godzin: nie zamyka prawidłowo niejawnego uchwytu pliku (ponieważ w ogóle nie wywołuje
close
).Na przykład robiąc to:
prowadzi do:
Dziwne jest to, że licznik linii
$.
jest zwiększany dla każdego pliku o jeden. Nie jest resetowany i nie zawiera liczby wierszy. I nie jest resetowany do zera podczas otwierania innego pliku, dopóki nie zostanie odczytany przynajmniej jeden wiersz. W moim przypadku robiłem coś takiego:Z powodu tego problemu warunek był fałszywy, ponieważ licznik linii nie został poprawnie zresetowany. Nie wiem, czy to błąd, czy po prostu zły kod ... Również wywołanie
close;
oderaclose STDIN;
nie pomaga.Zastąpiłem ten nieczytelny kod, używając open, konkatenacji ciągów i close. Jednak rozwiązanie opublikowane przez Brada Gilberta działa również, ponieważ zamiast tego używa jawnego uchwytu pliku.
Trzy wiersze na początku można zastąpić:
który prawidłowo zamyka uchwyt pliku.
źródło
Posługiwać się
wcześniej
$document = <FILE>;
.$/
to separator rekordów wejściowych , którym domyślnie jest znak nowej linii. Przedefiniowując go naundef
, mówisz, że nie ma separatora pól. Nazywa się to trybem „slurp”.Inne rozwiązania, takie jak
undef $/
ilocal $/
(ale niemy $/
) ponownie deklarują $ / i dają w ten sposób ten sam efekt.źródło
Możesz po prostu utworzyć podprogram:
źródło
Nie wiem, czy to dobra praktyka, ale używałem tego:
źródło
To wszystko są dobre odpowiedzi. ALE jeśli czujesz się leniwy, a plik nie jest tak duży, a bezpieczeństwo nie jest problemem (wiesz, że nie masz skażonej nazwy pliku), możesz wyskoczyć:
źródło
Możesz używać cat w systemie Linux:
źródło