Οι σημαίες#

Κάθε μονόγραμμο είναι ένας συνδυασμός ενός προγράμματος (που δίνεται στο -e ή στο -E) και μιας χούφτας σημαιών που τυλίγουν γύρω του σιωπηρή συμπεριφορά. Το κεφάλαιο αυτό καλύπτει τις σημαίες που θα χρειαστείτε. Καθεμία κερδίζει τη θέση της στα κεφάλαια προοδευτικότητας, regex και αριθμητικής που ακολουθούν.

Οι αναγνώστες που έρχονται από awk ή sed ξέρουν ήδη πώς μοιάζει η επανάληψη ανά γραμμή, η διάσπαση πεδίων και η επιτόπια επεξεργασία· το ερώτημα είναι ποια σημαία του pperl ενεργοποιεί την καθεμία.

-e - εκτέλεση προγράμματος που δίνεται στη γραμμή εντολών#

pperl -e 'print "hello\n"'

Το -e δέχεται ως όρισμα τον πηγαίο κώδικα Perl. Πολλαπλά κομμάτια -e συνενώνονται· συμπεριφέρονται ως ένα πρόγραμμα με ερωτηματικά ανάμεσά τους.

pperl -e 'my $x = 41;' -e 'print $x + 1, "\n"'    # 42

Χρησιμοποιήστε μονά εισαγωγικά γύρω από το πρόγραμμα ώστε το κέλυφος να αφήσει αδιάφορα τα $_, $1, \n και τους ανάστροφους χαρακτήρες. Δείτε το gotchas για το τι πάει στραβά με τα διπλά εισαγωγικά.

-E - -e συν το σύνολο σύγχρονων χαρακτηριστικών#

Το -E είναι το -e με ενεργοποιημένα όλα τα προαιρετικά χαρακτηριστικά: say, state, fc, τον τελεστή defined-or //, σημασιολογία συμβολοσειρών unicode υπό use feature 'unicode_strings', και άλλα.

pperl -E 'say "hello"'                    # instead of print "hello\n"
pperl -E 'say "pi = " . (atan2(1,1)*4)'

Καταφύγετε στο -E όταν γράφετε νέα μονογραμμικά. Καταφύγετε στο -e μόνο όταν έχει σημασία η συμβατότητα αντιγραφής-επικόλλησης με πολύ παλιά σενάρια.

-n - τύλιγμα σιωπηρού βρόχου ανάγνωσης γύρω από το πρόγραμμα#

Το -n μετατρέπει το πρόγραμμα σε σώμα βρόχου πάνω σε κάθε γραμμή κάθε αρχείου εισόδου (ή στο STDIN αν δεν δοθεί κανένα). Ο βρόχος είναι ακριβώς:

while (<>) {
    # your program
}

Το $_ κρατάει κάθε γραμμή εισόδου, συμπεριλαμβανομένου του τελικού χαρακτήρα αλλαγής γραμμής. Δεν τυπώνεται τίποτα αυτόματα - εσείς αποφασίζετε τι φτάνει στο STDOUT.

# Print lines containing "error"
pperl -ne 'print if /error/' app.log

Ισοδύναμη εκτεταμένη μορφή, που δείχνεται μία φορά ώστε να είναι σαφής η μηχανική επέκταση:

while (<>) {
    print if /error/;
}

Κάθε επόμενη συνταγή -n στον οδηγό βασίζεται σε αυτή την επέκταση - υποθέστε την χωρίς να την επανατυπώνετε.

Το BEGIN { } εκτελείται πριν τον βρόχο, το END { } εκτελείται μετά. Και τα δύο είναι κανονικά μπλοκ Perl και συνθέτονται καθαρά με το -n.

# Count lines matching a pattern
pperl -ne '$n++ if /WARN/; END { print "$n\n" }' app.log

-p - σαν το -n, αλλά τυπώνει το $_ μετά από κάθε επανάληψη#

pperl -pe 's/foo/bar/g' input.txt

Μηχανική επέκταση:

while (<>) {
    # your program
} continue {
    print or die "-p destination: $!";
}

Καταφύγετε στο -p όταν η έξοδος είναι η (πιθανώς τροποποιημένη) είσοδος. Καταφύγετε στο -n όταν η έξοδος είναι μια σύνοψη, ένα φιλτραρισμένο υποσύνολο ή τίποτα.

-l - χειρισμός τέλους γραμμής#

Το -l κάνει δύο πράγματα ταυτόχρονα:

  1. Στην είσοδο, chomp κάθε γραμμή καθώς διαβάζεται υπό -n / -p. Το $_ δεν τελειώνει πλέον σε "\n".

  2. Στην έξοδο, ορίζει το $\ (τον διαχωριστή εγγραφών εξόδου) ώστε κάθε print να προσαρτά "\n".

# Print just the first field of each tab-separated line
pperl -F'\t' -lane 'print $F[0]' table.tsv

Χωρίς το -l, είτε θα γράφατε print "$F[0]\n" (ο χαρακτήρας αλλαγής γραμμής μεταφέρεται μέσα στο πρόγραμμα) είτε θα παράγατε κολλημένη έξοδο.

Το -l δέχεται προαιρετικό οκταδικό όρισμα που ορίζει το $\ σε διαφορετικό χαρακτήρα: το -l012 διατηρεί τον χαρακτήρα αλλαγής γραμμής (την προεπιλογή), το -l0 ορίζει το $\ σε NUL, και ούτω καθεξής. Η συνηθισμένη χρήση είναι η μορφή χωρίς όρισμα.

-a - αυτόματη διάσπαση σε @F#

Σε συνδυασμό με -n ή -p, το -a διασπά το $_ σε λευκούς χαρακτήρες και τοποθετεί τα πεδία στο @F. Η προεπιλεγμένη διάσπαση είναι split(' ', $_) - περικόπτει τους λευκούς χαρακτήρες στην αρχή και αντιμετωπίζει κάθε διαδοχή λευκών χαρακτήρων ως έναν διαχωριστή.

# Third column of every line
pperl -lane 'print $F[2]' data.txt

# Reverse column order
pperl -lane 'print "@{[reverse @F]}"' data.txt

Το @F έχει δείκτες από το μηδέν. Το $F[-1] είναι το τελευταίο πεδίο. Το scalar @F είναι το πλήθος πεδίων.

-F - αλλαγή του μοτίβου διάσπασης#

-F sets the delimiter used by -a. The argument is a regex; a literal comma is -F,, a colon is -F:, a tab is -F'\t'.

# Second field of a colon-separated file
pperl -F: -lane 'print $F[1]' /etc/passwd

# Split on any run of commas or semicolons
pperl -F'[,;]+' -lane 'print scalar @F' mixed.csv

Το -F δεν υπαινίσσεται τίποτα για το -a· χρειάζεστε ούτως ή άλλως το -a. Το συνηθισμένο ιδίωμα -F: -lane σημαίνει διάσπαση με άνω κάτω τελεία, chomp εφαρμοσμένο, με το @F διαθέσιμο.

Η παρουσίαση στηλοθέτη απαιτεί κυριολεκτικό στηλοθέτη μέσα στο κέλυφος ή τη μορφή regex:

pperl -F'\t' -lane 'print $F[0]' data.tsv       # regex form, always safe
pperl -F'	' -lane 'print $F[0]' data.tsv     # literal tab - fragile

-i - επιτόπια επεξεργασία αρχείων#

Το -i ξαναγράφει το αρχείο από το οποίο διαβάζει το pperl, αντικαθιστώντας το περιεχόμενό του με ό,τι τυπώνει το -p. Όλη η έξοδος του αρχείου πηγαίνει σε ένα προσωρινό αρχείο· όταν ο βρόχος τελειώσει, αυτό το προσωρινό αντικαθιστά το πρωτότυπο.

# Replace CRLF with LF in every .txt under cwd (no backup)
pperl -i -pe 's/\r\n/\n/g' *.txt

# Same, keeping a .bak copy beside each original
pperl -i.bak -pe 's/\r\n/\n/g' *.txt

Πάντα να χρησιμοποιείτε -i.bak (ή άλλη κατάληξη) μέχρι να επαληθεύσετε την επεξεργασία πάνω σε αντιπροσωπευτικό αρχείο. Ένα σφάλμα στο πρόγραμμα με σκέτο -i καταστρέφει την είσοδο. Δείτε το gotchas.

Το -i δεν έχει αποτέλεσμα χωρίς -p (ή ρητές εκτυπώσεις υπό -n): αν δεν τυπωθεί τίποτα, το αρχείο αντικατάστασης είναι κενό.

-M και -m - φόρτωση αρθρωμάτων πριν εκτελεστεί το πρόγραμμα#

Το -Mmodule ισοδυναμεί με use module; στην κορυφή του προγράμματος. Το -Mmodule=sym1,sym2 είναι use module qw(sym1 sym2);.

pperl -MList::Util=sum -lane 'print sum @F' data.txt
pperl -MPOSIX=strftime -le 'print strftime("%F", localtime)'
pperl -MData::Dumper -e 'print Dumper({a=>1, b=>[2,3]})'

Το πεζό -m είναι no strict αντί για use · σπάνια χρειάζεται στη γραμμή εντολών.

Πιο συνηθισμένα αρθρώματα σε μονογραμμικά: List::Util (sum/min/max/uniq/any), POSIX (strftime, mktime, fmod), Data::Dumper (επιθεώρηση δομών), JSON::PP (ανάλυση/εκπομπή JSON), Text::CSV (CSV με εισαγωγικά), MIME::Base64, Digest::MD5, Digest::SHA, Socket.

-0 - ορισμός του διαχωριστή εγγραφών εισόδου#

Η Perl κανονικά διαβάζει μία γραμμή τη φορά. Το -0NNN ορίζει το $/ στον χαρακτήρα με τον δοσμένο οκταδικό κωδικό, αλλάζοντας τι σημαίνει «μία εγγραφή» για τα <>, <STDIN> και τον βρόχο -n / -p.

Συνηθισμένες μορφές:

Μορφή

Σε τι γίνεται το $/

Αποτέλεσμα

-0

"\0" (NUL)

Διάβασμα εγγραφών οριοθετημένων με NUL (ταιριάζει με find -print0).

-0777

undef

Slurp ολόκληρου του αρχείου ως μία εγγραφή.

-00

""

Λειτουργία παραγράφου: οι κενές γραμμές διαχωρίζουν εγγραφές.

-0NNN

chr(0NNN)

Οποιοδήποτε μεμονωμένο οκταδικό byte.

# Count files from find -print0
find . -type f -print0 | pperl -0 -ne '$n++; END { print "$n\n" }'

# Slurp, then run a cross-line regex
pperl -0777 -ne 'print "yes\n" if /BEGIN.*?END/s' text.txt

# Print every paragraph containing "TODO"
pperl -00 -ne 'print if /TODO/' notes.txt

Η λειτουργία παραγράφου (-00) αλληλεπιδρά με το -l: χωρίς -l, ο κενός διαχωριστής παραμένει προσαρτημένος σε κάθε εγγραφή· με -l, εφαρμόζεται chomp.

-C - Unicode σε stdio ή/και @ARGV#

Το -C ενεργοποιεί τον χειρισμό Unicode σε καθορισμένα ρεύματα. Το όρισμα είναι είτε αριθμός (μάσκα bits) είτε συμβολοσειρά γραμμάτων.

pperl -CSD -ne 'print' input.txt      # stdin, stdout, stderr all UTF-8
pperl -CA  -e  'print $ARGV[0]' äöü   # @ARGV treated as UTF-8
pperl -CSA -nE 'say length'           # S + A

Κωδικοί γραμμάτων: I = stdin, O = stdout, E = stderr, S = I+O+E, A = @ARGV, D = ορίζει προεπιλεγμένα στρώματα I/O (συμπεριλαμβάνει ανοίγματα αρχείων).

Για πλήρως UTF-8 συνεδρία, -CSD. Για εφάπαξ επεξεργασία ονομασμένων αρχείων UTF-8, -CSAD. Δείτε το gotchas για τα συμπτώματα που σας λένε ότι λείπει το -C.

Πίνακας αναφοράς#

Κάθε σημαία, η μηχανική επέκτασή της και το κεφάλαιο όπου εμφανίζεται πρώτη φορά σε συνταγή.

Σημαία

Επεκτείνεται σε

Πρώτη χρήση στο

-e CODE

Εκτέλεση του CODE ως προγράμματος

progression

-E CODE

-e συν όλα τα τρέχοντα χαρακτηριστικά ενεργοποιημένα

progression

-n

while (<>) { CODE }

progression

-p

while (<>) { CODE } continue { print }

progression

-l

chomp εισόδου υπό -n/-p· ορίζει $\ = "\n" για την έξοδο

progression

-a

Αυτόματη διάσπαση του $_ σε @F

progression

-F PAT

Αλλαγή του μοτίβου διάσπασης του -a στο regex PAT

progression

-i[EXT]

Επιτόπια επεξεργασία· με EXT, διατηρεί αντίγραφο ασφαλείας original + EXT

progression

-M MOD

use MOD; πριν το πρόγραμμα

numeric

-M MOD=X

use MOD qw(X);

numeric

-0

$/ = "\0" - εγγραφές οριοθετημένες με NUL

progression

-00

$/ = "" - λειτουργία παραγράφου

progression

-0777

$/ = undef - slurp ολόκληρου αρχείου

progression

-C

Ενεργοποίηση Unicode στο stdio, στο @ARGV ή/και στα προεπιλεγμένα στρώματα

gotchas

Ειδικές μεταβλητές που στήνουν οι σημαίες#

Σύντομος κατάλογος· οι πλήρεις ορισμοί ζουν στο perlvar.

Μεταβλητή

Ρόλος υπό -n/-p

$_

Η τρέχουσα γραμμή εισόδου (chomped αν -l, ωμή αλλιώς).

$.

Τρέχων αριθμός γραμμής εισόδου (δεν μηδενίζεται μεταξύ αρχείων από προεπιλογή).

$/

Διαχωριστής εγγραφών εισόδου. Η οικογένεια -0 τον αλλάζει.

$\

Διαχωριστής εγγραφών εξόδου που προσαρτά το print. Το -l τον ορίζει σε "\n".

$,

Διαχωριστής πεδίων εξόδου που εισάγεται ανάμεσα στα ορίσματα του print.

$"

Διαχωριστής ανάμεσα στα στοιχεία πίνακα όταν παρεμβάλλονται σε "@array".

@F

Πεδία αυτόματης διάσπασης υπό -a.

@ARGV

Εναπομείναντα ορίσματα γραμμής εντολών· τα ονόματα αρχείων καταναλώνονται καθώς επεξεργάζονται.

$ARGV

Όνομα του αρχείου που διαβάζεται τη στιγμή αυτή (το "-" σημαίνει STDIN).

Μάθετε περισσότερα#

  • Το progression εφαρμόζει κάθε σημαία σε συνταγές αυξανόμενης πολυπλοκότητας.

  • Το perlvar απαριθμεί κάθε ειδική μεταβλητή που ορίζει το pperl, όχι μόνο εκείνες που αγγίζουν οι σημαίες.

  • Το perlop καλύπτει το qr//, τον τελεστή flip-flop και τον τελεστή «διαμάντι» που χρησιμοποιούν οι βρόχοι -n / -p.