O singură linie
În informatică, un singur liner (tradus din engleză ca „mono-linie”) este o intrare a unei singure linii de cod furnizate unui interpret de comandă pentru a efectua o anumită sarcină. Termenul este folosit prin extensie pentru a indica un program în orice limbă care îndeplinește o funcție non-trivială într-o singură linie de cod. Un one-liner este de obicei scris în limba shell-ului pe care este executat sau invocă un alt interpret și îi transmite codul de executat, mai rar invocă un compilator , furnizând sursa de compilare și instrucțiuni de executare a software-ului compilat .
Unele limbaje de scriptare dinamice, cum ar fi awk , sed și Perl, sunt utilizate în mod tradițional pentru a scrie one-liners . One-liners sunt uneori folosite pentru a arăta expresivitatea unui limbaj de programare sau abilitatea unui programator și există competiții al căror scop este să creeze one-liners deosebit de compacte și expresive.
Istorie
Expresia one-liner apare de două ori în indexul cărții The AWK Programming Language [1] (cunoscut sub acronimul TAPL ) de Alfred Aho , Peter Weinberger și Brian Kernighan , cel mai semnificativ text de referință pentru limbajul awk . Autorii explică nașterea paradigmei one-liner în lucrările lor pe primele mașini Unix :
( EN ) „Versiunea din 1977 avea doar câteva variabile încorporate și funcții predefinite. A fost conceput pentru a scrie programe scurte [...] Modelul nostru a fost acela că o invocație va avea una sau două linii, introdusă și utilizată imediat. Implicitele au fost alese pentru a se potrivi acestui stil [...] Noi, fiind autorii, știam cum ar trebui să fie folosit limba și, așadar, am scris doar un singur liner. " | ( IT ) „Versiunea din 1977 avea doar câteva variabile încorporate și funcții predefinite. A fost conceput pentru a scrie programe scurte [...] Modelul nostru a prezis că invocarea avea una sau două rânduri, a fost introdusă și utilizată imediat. Setările implicite au fost alese pentru a se potrivi acestui stil [...] Noi, fiind autorii, știam cum ar trebui să fie folosit limba și, ca rezultat, am scris doar un singur liner . " |
( Limbajul de programare AWK ) |
Această primă definiție a unui singur liner implică executarea imediată a programului fără compilare, deci s-ar referi doar la codul sursă al limbajelor interpretate. Cu toate acestea, în 1985 a fost adăugată la IOCCC o categorie pentru cele mai bune garnituri în limbajul C , care este compilată în schimb.
Exemple
AWK
Cartea AWK Programming Language conține douăzeci de exemple de one-liners [2] la sfârșitul primului capitol. Printre acestea se numără următoarele:
- Imprimați numărul total de linii ale intrării:
END {print NR}
- Imprimați a zecea linie în intrare:
NR == 10
- Imprimați ultimul câmp al fiecărei linii de intrare:
{print $ NF}
C.
Următorul este un exemplu de un singur liner în C (câștigător al IOCCC „Cel mai bun one-liner”).
main ( int c , char ** v ) { return ! m ( v [ 1 ], v [ 2 ]);} m ( char * s , char * t ) { return * t -42 ? * s ? 63 == * t | * s == * t && m ( s + 1 , t + 1 ) :! * T : m ( s , t + 1 ) || * s && m ( s + 1 , t ); }
Este un potrivitor de modele glob, care recunoaște caracterele „*” (zero sau mai multe caractere) și „?” (exact un personaj), asemănător majorității shell-urilor Unix. Se execută cu doi parametri, un șir și un model, iar starea de ieșire este 0 dacă se produce potrivirea modelului, 1 altfel. Modelul trebuie să identifice întregul șir, pentru a identifica un șir de caractere, trebuie doar să adăugați un asterisc la începutul și la sfârșitul modelului. Exemple de utilizare:
$ prog foo 'f ??' ; ecou $?
$ prog 'cel mai bun program scurt' '?? st * o ** p? *' ; ecou $?
Haskell
Următorul one-liner din Haskell efectuează sortare lexicografică (conform ordinii ASCII ) a liniilor de intrare. [3]
main = ( mapM_ putStrLn . Date . List . sort . lines ) = << getContents
O altă versiune compactă:
principal = interacționează ( unlines . Date . List . sort . lines )
Poate fi invocat din linia de comandă cu:
numele fișierului pisicii | ghc -e "interacționează (unlines. Data.List.sort. lines)"
J
Câteva exemple în J :
- Funcție medie care returnează media unei liste de numere:
medie =: + /% #
- Quicksort :
quicksort =: (( $: @ ( <# [ ) , ( = # [ ) , $: @ ( > # [ )) ( {~ ? @ # )) ^: ( 1 <# )
OCaml
O funcție care verifică suma de control cu formula lui Luhn pe o listă de numere întregi.
let luhn l = fst ( List . fold_right ( fun x ( a , s ) -> a + s * x / 10 + s * x mod 10 , 3 - s ) l ( 0 , 1 )) mod 10 = 0
Perl
Câteva exemple în Perl :
- Căutați cuvinte duplicat
perl -0777 -ne ' print "$.: doubled $_\n" while /\b(\w+)\b\s+\b\1\b/gi
'
- Găsiți palindromi în / usr / dict / cuvinte
perl -lne ' print if $_ eq reverse
' / usr / dict / words
- Înlocuiți șirul „foo” cu șirul „bara” din fișierele locale cu extensia .c:
perl -p -i.bak -e ' s/\bfoo\b/bar/g
' * .c
- Inversați toți octeții dintr-un fișier:
perl -0777e 'print scalar reverse <>' nume de fișier
Multe Perl one-liners sunt imperative , dar suportul Perl pentru funcții anonime, închideri , hărți, filtre (grep) și folduri (List :: Util :: reduce) permite crearea de one-liners funcționale . De exemplu, următorul one-liner definește o funcție care returnează o listă csv a primelor până la valoarea transmisă ca parametru:
$ z meu = sub { grep { $ a = $ _ ; ! grep { ! ( $ a % $ _ ) } ( 2 .. $ _ - 1 )} ( 2 .. $ _ [ 0 ]) }
Poate fi invocat din linia de comandă după cum urmează:
perl -e ' $, = "," ; print sub { grep { $a = $_ ; !grep { ! ( $a % $_ ) } ( 2 .. $_ -1 )} ( 2 .. $_ [ 0 ]) } -> ( shift )
'n
pentru a imprima o listă a primelor între 2 și n.
PowerShell
Un exemplu de un singur liner în PowerShell care găsește palindromi în fișierul words.txt:
cuvinte de pisică . txt | % { if ( $ _ -eq ( $ _ [- 1 ..- ( $ _ . length )] -join '' )) { $ _ }}
Acest exemplu ia ca intrare o listă de nume și valori într-un fișier CSV și returnează suma valorilor corespunzătoare fiecărui nume:
ipcsv . \ fruit . txt - H F , C | Grupul F |% {@ { " $ ( $ _ . Nume ) " = ( $ _ . Grup | măsura C -sum ). Suma }} | sortare valoare
Piton
Următoarea linie Python definește funcția qs
, care scurtează o matrice:
qs = lambda p = Niciuna , * l : [] dacă p este Nimeni altul qs ( * [ x pentru x în l dacă x < p ]) + [ p ] + qs ( * [ x pentru x în l dacă x > = p ])
Python nu este un limbaj de formulare liber și instrucțiunile sunt separate prin returnări de transport, în plus, lambdas poate conține o singură expresie, astfel încât crearea de linii într-un program poate să nu fie întotdeauna imediată. One-liners pot fi construite cu ușurință pe linia de comandă, utilizând steagul -cmd (sau aliasul abreviat -c) și necesită de obicei importul unuia sau mai multor module. Instrucțiunile sunt separate cu „;” în loc de întoarcerea obișnuită a trăsurii. De exemplu, pentru a imprima ultimul câmp de intrare standard:
ls -l | python -c " import sys ;[ sys . stdout . write ( ' ' . join ([ line . split ( ' ' )[ - 1 ]])) for line in sys . stdin ]
"
Au fost dezvoltate mai multe scripturi pentru a facilita construirea unui singur liner în Python, cum ar fi pyp [4] sau Pyline [5] , care importă module utilizate în mod obișnuit și oferă variabile și funcționalitate mai ușor de citit de om. De exemplu:
ls -l | pyp "spațiul alb [-1]" # "spațiul alb" conține jetoane separate prin spații albe în pyp
ls -l | pyline "cuvinte [-1]" # "cuvinte" conține jetoane separate în spațiu în pyline
Rachetă
Următorul program Racket este echivalent cu exemplul anterior din Haskell:
# lang racket
( pentru-fiecare displayln ( sortare ( port-> linii ) șir <? ))
invocabil din linia de comandă cu:
racket -e ' ( for-each displayln ( sort ( port->lines ) string<? ))
'
Notă
Elemente conexe
linkuri externe
- Instrumente Unix simple , comenzi Unix implementate într-o singură linie de Haskell
- awk one-liners ( TXT ), pe pement.org .
- sed one-liners ( TXT ), la sed.sourceforge.net .
- Awk și Sed One-Liners Explained , pe osnews.com .
- Perl One Liners , exemple practice
- Mai multe linii Perl One , la novosial.org .
- Concurs internațional de cod C ofuscat, IOCCC