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).

 15
Author: Will, 2008-09-21

24 answers

Proszę zobaczyć moje slajdy dla "Przewodnik po opcjach wiersza poleceń Perla."

 14
Author: Andy Lester,
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.

 11
Author: Ovid,
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'
}
 11
Author: jfs,
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/'
 11
Author: pjf,
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.)

 9
Author: John Siracusa,
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.

 7
Author: J.F. Sebastian,
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'
 6
Author: ,
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 22:33:34

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.

 4
Author: dland,
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;
 4
Author: jfs,
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.

 3
Author: jkramer,
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.

 3
Author: jtimberman,
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{$_}++;}'`)
 3
Author: dr_pepper,
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
 3
Author: JDrago,
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
 3
Author: Tim Lewis,
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.

 3
Author: Peter Mortensen,
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.

 2
Author: melo,
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}'
 2
Author: Adam Bellaire,
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 /^/'
 2
Author: mtk,
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.

 2
Author: Benny,
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.

 1
Author: ephemient,
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.

 1
Author: singingfish,
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.

 1
Author: Benny,
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" ;
 0
Author: Kwondri,
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])
 -5
Author: jkramer,
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