Jaki jest twój najnowszy przydatny Perl one-liner(lub fajka z perlem)? [zamknięte]
Jednowierszowy powinien:
- rozwiąż prawdziwy problem
- nie być szeroko tajemniczy (powinien być łatwy do zrozumienia i odtworzenia)
- być wart czasu potrzebnego na napisanie tego (nie powinno być zbyt mądre)
Szukam praktycznych porad i trików(komplementarne przykłady dla perldoc perlrun
).
24 answers
Proszę zobaczyć moje slajdy dla "Przewodnik po opcjach wiersza poleceń Perla."
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 19:54:29
Możesz nie myśleć o tym jak o perlu, ale używam ack religijnie (jest to inteligentny zamiennik grepa napisany w Perlu) i to pozwala mi edytować, na przykład, wszystkie moje testy Perla, które uzyskują dostęp do określonej części naszego API:
vim $(ack --perl -l 'api/v1/episode' t)
Na marginesie, jeśli używasz Vima, możesz uruchomić wszystkie testy w buforach edytora .
Dla czegoś bardziej oczywistego (jeśli prostego) Perla, musiałem wiedzieć, ile programów testowych używało urządzeń testowych w katalogu t / lib / TestPM (Wyciąłem polecenie dla jasności).
ack $(ls t/lib/TestPM/|awk -F'.' '{print $1}'|xargs perl -e 'print join "|" => @ARGV') aggtests/ t -l
Zauważ, jak "join" zamienia wyniki w wyrażenia regularne, aby przesłać je do ack.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 08:05:54
problem: Odtwarzacz multimedialny nie ładuje automatycznie napisów, ponieważ ich nazwy różnią się od odpowiednich plików wideo.
rozwiązanie : Zmień nazwę wszystkich *.srt (pliki z napisami), aby pasowały do *.avi (pliki z wideo).
perl -e'while(<*.avi>) { s/avi$/srt/; rename <*.srt>, $_ }'
Zastrzeżenie: Kolejność sortowania oryginalnych plików wideo i napisów powinna być taka sama.
Tutaj bardziej wyrazista wersja powyższej jednowersowej:
my @avi = glob('*.avi');
my @srt = glob('*.srt');
for my $i (0..$#avi)
{
my $video_filename = $avi[$i];
$video_filename =~ s/avi$/srt/; # 'movie1.avi' -> 'movie1.srt'
my $subtitle_filename = $srt[$i]; # 'film1.srt'
rename($subtitle_filename, $video_filename); # 'film1.srt' -> 'movie1.srt'
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-23 07:12:06
Pliki dziennika Squid. Są świetne, prawda? Z tym, że domyślnie mają pole czasu seconds-from-the-epoch. Oto jedna linijka, która odczytuje z pliku dziennika squid i konwertuje czas na czytelną dla człowieka datę:
perl -pe's/([\d.]+)/localtime $1/e;' access.log
Dzięki niewielkiemu dostosowaniu możesz wyświetlać tylko linie ze słowem kluczowym, które Cię interesuje. Następujące Zegarki dla stackoverflow.com uzyskuje dostęp i drukuje tylko te linie, z czytelną dla człowieka datą. Aby uczynić go bardziej użytecznym, daję mu wyjście z tail -f
, więc widzę dostęp w czasie rzeczywistym:
tail -f access.log | perl -ne's/([\d.]+)/localtime $1/e,print if /stackoverflow\.com/'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-22 13:37:07
Wspólny idiom używania find ... -exec rm {} \;
do usuwania zestawu plików gdzieś w drzewie katalogów nie jest szczególnie skuteczny, ponieważ wykonuje polecenie rm
raz dla każdego znalezionego pliku. Jeden z moich nawyków, zrodzony z czasów, gdy komputery nie były tak szybkie (dagnabbit!w języku perl istnieje wiele wywołań do rm
:
find . -name '*.whatever' | perl -lne unlink
perl
część wiersza poleceń odczytuje listę plików emitowanych* przez find
, po jednym na linię, przycina znak nowej linii i usuwa plik za pomocą wbudowana w Perla funkcja unlink()
, która przyjmuje $_
jako swój argument, jeśli nie podano jawnego argumentu. ($_
jest ustawiana na każdą linię wejścia dzięki znacznikowi -n
.) (*Obecnie większość komend find
domyślnie wykonuje -print
, więc mogę pominąć tę część.)
Podoba mi się ten idiom nie tylko ze względu na wydajność (być może mniej ważny w dzisiejszych czasach), ale także dlatego, że ma mniej akordowanych/niezręcznych klawiszy niż pisanie tradycyjnej sekwencji -exec rm {} \;
. Unika również cytowania problemów spowodowanych przez plik nazwy ze spacjami, cudzysłowami itp., których mam wiele. (Bardziej rozbudowana wersja może użyć opcji find
-print0
, a następnie poprosić perl
o odczytanie rekordów rozdzielonych null zamiast linii, ale zazwyczaj jestem całkiem pewien, że moje nazwy plików nie zawierają osadzonych nowych linii.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-03 04:31:21
Wszystkie jednolinijkowe odpowiedzi zebrane w jednym miejscu:
perl -pe's/([\d.]+)/localtime $1/e;' access.log
ack $(ls t/lib/TestPM/|awk -F'.' '{print $1}'|xargs perl -e 'print join "|" => @ARGV') aggtests/ t -l
perl -e'while(<*.avi>) { s/avi$/srt/; rename <*.srt>, $_ }'
find . -name '*.whatever' | perl -lne unlink
tail -F /var/log/squid/access.log | perl -ane 'BEGIN{$|++} $F[6] =~ m{\Qrad.live.com/ADSAdClient31.dll} && printf "%02d:%02d:%02d %15s %9d\n", sub{reverse @_[0..2]}->(localtime $F[0]), @F[2,4]'
export PATH=$(perl -F: -ane'print join q/:/, grep { !$c{$_}++ } @F'<<<$PATH)
alias e2d="perl -le \"print scalar(localtime($ARGV[0]));\""
perl -ple '$_=eval'
perl -00 -ne 'print sort split /^/'
perl -pe'1while+s/\t/" "x(8-pos()%8)/e'
tail -f log | perl -ne '$s=time() unless $s; $n=time(); $d=$n-$s; if ($d>=2) { print qq ($. lines in last $d secs, rate ),$./$d,qq(\n); $. =0; $s=$n; }'
perl -MFile::Spec -e 'print join(qq(\n),File::Spec->path).qq(\n)'
Zobacz odpowiednie odpowiedzi dla ich opisy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 21:35:54
Perl jednowierszowy, którego używam najczęściej, to kalkulator Perla
perl -ple '$_=eval'
Jednym z największych świństw pasma w $work jest pobieranie reklamy internetowej, więc patrzę na nisko wiszące owoce czekające na zbieranie. Pozbyłem się Google ads, teraz mam Microsoft w zasięgu wzroku. Więc uruchamiam ogon w pliku dziennika i wybieram interesujące linie:
tail -F /var/log/squid/access.log | \
perl -ane 'BEGIN{$|++} $F[6] =~ m{\Qrad.live.com/ADSAdClient31.dll}
&& printf "%02d:%02d:%02d %15s %9d\n",
sub{reverse @_[0..2]}->(localtime $F[0]), @F[2,4]'
Rura Perla zaczyna się od ustawienia autoflush na true, tak aby każde działanie było natychmiast wydrukowane. W przeciwnym razie wyjście, które zostało pobrane i otrzymuje się partię linii, gdy bufor wyjściowy wypełnia się. Przełącznik-a dzieli każdą linię wejściową na białą spację i zapisuje wyniki w tablicy @F (funkcjonalność zainspirowana możliwościami awk do dzielenia rekordów wejściowych na $1, $2, $3... zmienne).
Sprawdza, czy siódme pole w linii zawiera poszukiwany URI (używając \Q, aby oszczędzić nam bólu ucieczki nieciekawych metacharakterów). Jeśli dopasowanie zostanie znalezione, wyświetli czas, źródłowy adres IP i liczbę bajtów zwróconych z pilota miejscu.
Czas jest uzyskiwany przez pobranie czasu epoch w pierwszym polu i użycie' localtime ' do rozbicia go na jego składniki (godzina, minuta, sekunda, dzień, miesiąc, rok). Zajmuje kawałek pierwszych trzech elementów zwraca, second, minute i hour, i odwraca kolejność, aby uzyskać hour, minute i second. Jest to zwracane jako tablica trzyelementowa, wraz z wycinkiem trzeciej (adresu IP) i piątej (rozmiaru) z oryginalnej tablicy @F. Te pięć argumentów przekazywane są do sprintf, który formatuje wyniki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 07:41:54
@dr_pepper
Usuń literal duplikaty w $PATH
:
$ export PATH=$(perl -F: -ane'print join q/:/, grep { !$c{$_}++ } @F'<<<$PATH)
Wypisuje unikalne czyste ścieżki ze zmiennej środowiskowej %PATH%
(nie dotyka ../
i podobnie, zastąp File::Spec->rel2abs
przez Cwd::realpath
jeśli jest to pożądane) nie jest to jednoliniowa, aby była bardziej przenośna:
#!/usr/bin/perl -w
use File::Spec;
$, = "\n";
print grep { !$count{$_}++ }
map { File::Spec->rel2abs($_) }
File::Spec->path;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 23:21:59
W odpowiedzi na kombinację Ovids vim/ACK:
Ja też często czegoś Szukam, a potem chcę otworzyć pasujące pliki w Vimie, więc jakiś czas temu zrobiłem sobie mały skrót (chyba działa tylko w ZSH):
function vimify-eval; {
if [[ ! -z "$BUFFER" ]]; then
if [[ $BUFFER = 'ack'* ]]; then
BUFFER="$BUFFER -l"
fi
BUFFER="vim \$($BUFFER)"
zle accept-line
fi
}
zle -N vim-eval-widget vimify-eval
bindkey '^P' vim-eval-widget
Działa to tak: szukam czegoś za pomocą ack, na przykład ack some-pattern
. Patrzę na wyniki i jeśli mi się podoba, wciskam strzałkę w górę, aby ponownie uzyskać linię ack, a następnie wciskam CTRL + P. co się wtedy dzieje, ZSH dopisuje i "- l " do listy nazw plików tylko wtedy, gdy polecenie zaczyna się od "ack". Następnie umieszcza się "$(...) "wokół komendy i" vim " przed nią. Wtedy wszystko zostanie wykonane.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 12:23:22
Używam tego dość często, aby szybko przekonwertować czasy epoki na użyteczny datestamp.
perl -l -e 'print scalar(localtime($ARGV[0]))'
Stwórz alias w swojej powłoce:
alias e2d="perl -le \"print scalar(localtime($ARGV[0]));\""
Następnie podłącz numer epoki do aliasu.
echo 1219174516 | e2d
Wiele programów i narzędzi na Unix/Linux używa wartości epoch do reprezentowania czasu, więc okazało się to dla mnie nieocenione.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 22:18:26
Usuń duplikaty w zmiennej path:
set path=(`echo $path | perl -e 'foreach(split(/ /,<>)){print $_," " unless $s{$_}++;}'`)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-01 20:08:03
Usuń zakończenia linii MS-DOS.
perl -p -i -e 's/\r\n$/\n/' htdocs/*.asp
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-03 18:55:28
Często muszę zobaczyć czytelną wersję ścieżki podczas skryptowania powłoki. Poniższe jednolinijki wypisują każdy wpis ścieżki w jego własnej linii.
Z biegiem czasu ta jednowierszowa ewoluowała przez kilka faz:
UNIX (Wersja 1):
perl -e 'print join("\n",split(":",$ENV{"PATH"}))."\n"'
Windows (Wersja 2):
perl -e "print join(qq(\n),split(';',$ENV{'PATH'})).qq(\n)"
Both UNIX / Windows (using Q/qq tip from @j-f-sebastian) (version 3):
perl -MFile::Spec -e 'print join(qq(\n),File::Spec->path).qq(\n)' # UNIX
perl -MFile::Spec -e "print join(qq(\n),File::Spec->path).qq(\n)" # Windows
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-27 15:46:49
Wyodrębnianie reputacji przepełnienia stosu bez konieczności otwierania strony internetowej:
perl -nle "print ' Stack Overflow ' . $1 . ' (no change)' if /\s{20,99}([0-9,]{3,6})<\/div>/;" "SO.html" >> SOscores.txt
Zakłada to, że strona Użytkownika została już pobrana do pliku.html. Używam wget do tego celu. Zapis ten jest przeznaczony dla wiersza poleceń systemu Windows; będzie nieco inny dla Linuksa lub Mac OS X. wyjście jest dołączane do pliku tekstowego.
Używam go w skrypcie BAT do automatyzacji próbkowania reputacji na czterech stronach w rodzinie: Przepełnienie stosu, błąd serwera, Super User i Meta stos Przepełnienie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-18 21:18:54
Jeden z ostatnich, który dostał miejsce w moim ~ / bin:
perl -ne '$s=time() unless $s; $n=time(); $d=$n-$s; if ($d>=2) { print "$. lines in last $d secs, rate ",$./$d,"\n"; $. =0; $s=$n; }'
Użyjesz go przeciwko ogonowi pliku dziennika i wyświetli szybkość wyświetlanych wierszy.
Chcesz wiedzieć, ile odsłon na sekundę dostajesz na swoim serwerze? tail - f log / this_script.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-04 11:38:12
Get human-readable output from du
, posortowane według rozmiaru:
perl -e '%h=map{/.\s/;7x(ord$&&10)+$`,$_}`du -h`;print@h{sort%h}'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-17 18:56:27
Filtruje strumień oddzielonych od siebie wyrazów (lista par nazwa / wartość), sortowanie każdej zwrotki indywidualnie:
perl -00 -ne 'print sort split /^/'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-22 16:18:50
Administratorzy sieci mają tendencję do błędnej konfiguracji "adresu podsieci" jako "adresu hosta", szczególnie podczas korzystania z automatycznego sugerowania Cisco ASDM. Ten prosty jednowierszowy skanuje pliki konfiguracyjne w poszukiwaniu takich błędów konfiguracyjnych.
Niepoprawne użycie: permit host 10.1.1.0
Poprawne użycie: permit 10.1.1.0 255.255.255.0
perl -ne "print if /host ([\w\-\.]+){3}\.0 /" *.conf
To zostało przetestowane i używane w systemie Windows, Proszę zasugerować, czy powinno być zmodyfikowane w jakikolwiek sposób dla prawidłowego użytkowania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-16 08:38:47
Rozwiń wszystkie tabulatory do spacji: perl -pe'1while+s/\t/" "x(8-pos()%8)/e'
Oczywiście można to zrobić za pomocą :set et, :ret w Vim.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-01 19:59:59
Mam listę tagów, za pomocą których identyfikuję fragmenty tekstu. Lista główna ma format:
text description {tag_label}
Ważne jest, aby {tag_label}
nie były powielane. Jest taki fajny prosty skrypt:
perl -ne '($c) = $_ =~ /({.*?})/; print $c,"\n" ' $1 | sort | uniq -c | sort -d
Wiem, że mogłem zrobić wszystko w shell lub perlu, ale to była pierwsza rzecz, która przyszła mi do głowy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-17 23:59:21
Często musiałem konwertować dane tabelaryczne do plików konfiguracyjnych. Na przykład dostawcy okablowania sieciowego dostarczają rekord łatania w formacie Excel i musimy użyć tych informacji do tworzenia plików konfiguracyjnych. i. E,
Interface, Connect to, Vlan
Gi1/0/1, Desktop, 1286
Gi1/0/2, IP Phone, 1317
Powinno zostać:
interface Gi1/0/1
description Desktop
switchport access vlan 1286
I tak dalej. To samo zadanie pojawia się ponownie w kilku formach w różnych zadaniach administracyjnych, gdzie dane tabelaryczne muszą być poprzedzone nazwą pola i przetransponowane do płaskiej struktury. Widziałem, że DBA marnuje dużo razy przygotowując swoje instrukcje SQL z arkusza excel. Można to osiągnąć za pomocą tego prostego jednowarstwowego. Po prostu zapisz dane tabelaryczne w formacie CSV za pomocą ulubionego narzędzia do arkusza kalkulacyjnego i uruchom to jednoliniowe narzędzie. Nazwy pól w wierszu nagłówka są dołączane do poszczególnych wartości komórek, więc być może będziesz musiał je edytować, aby spełnić swoje wymagania.
perl -F, -lane "if ($.==1) {@keys = @F} else{print @keys[$_].$F[$_] foreach(0..$#F)} "
Zastrzeżenie jest takie, że żadna z nazw lub wartości pól nie powinna zawierać przecinków. Być może można to dalej rozwinąć, aby wyłapać takie wyjątki w jednolinijkowy, proszę poprawić to, jeśli to możliwe.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-25 08:16:30
Oto jeden, który przydaje mi się w przypadku skompresowanych plików dziennika kolekcji:
open STATFILE, "zcat $logFile|" or die "Can't open zcat of $logFile" ;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 13:31:48
W pewnym momencie odkryłem, że wszystko, co chciałbym zrobić z perlem, które jest wystarczająco krótkie, aby można było zrobić w wierszu poleceń z 'perl-e' , można zrobić lepiej, łatwiej i szybciej z normalnymi funkcjami ZSH bez kłopotów z cytowaniem. Np. powyższy przykład można zrobić tak:
for foo in *.avi; mv *.srt ${foo:r}.srt
UPDATE
The onliner aboughly wrong, sorry za nie czytanie uważnie. Oto poprawna wersja:
srt=(*.srt); for foo in *.avi; mv $srt[1] ${foo:r}.srt && srt=($srt[2,-1])
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-22 12:14:36