13 ms·
Useful Perl one-liners (2013)
- 0xmohit 10y agoReminds of sed and awk one liners: http://sed.sourceforge.net/sed1line.txt http://sed.sourceforge.net/sed1line.txt http://www.pement.org/awk/awk1line.txt http://www.pement.org/awk/awk1line.txt
- pkrumins 10y agoThat's exactly how perl1line.txt was created. Also I did article series explaining every single one of sed1liners, awk1liners and perl1liners in those files: http://www.catonmat.net/blog/sed-one-liners-explained-part-one/ http://www.catonmat.net/blog/sed-one-liners-explained-part-o... http://www.catonmat.net/blog/awk-one-liners-explained-part-one/ http://www.catonmat.net/blog/awk-one-liners-explained-part-o... http://www.catonmat.net/blog/perl-one-liners-explained-part-one/ http://www.catonmat.net/blog/perl-one-liners-explained-part-...
- tyingq 10y agoI use perl with find quite a bit...it's great for doing something with a list of files without spawning a bunch of processes via -exec. Like, for example: # delete a bunch of matching files and print the name find . -name whatever\* -type f | perl -ne 'print;chomp;unlink'
- vesinisa 10y agoI think you can achieve exactly the same without pipes with: > find . -name whatever\* -type f -print -delete ... except this variation should be safe with filenames containing the '\n' character (which is perfectly legal on most UNIXes).
- JadeNB 10y ago> > find . -name whatever\* -type f -print -delete Or you can also do it all in Perl: perl -E 'while (<whatever*>) { say; unlink }' EDIT: As tyingq points out (https://news.ycombinator.com/item?id=13065132 https://news.ycombinator.com/item?id=13065132), I forgot that `find` recurses into subdirectories. I don't know a way to make Perl do the same that doesn't start getting more verbose (but there must be a Perl golfer somewhere around here who does …).
- tyingq 10y agoThat doesn't recurse into subdirectories.
- EvilTerran 10y ago> there must be a Perl golfer somewhere around here who does … Hello! perl -MFile::Find -e 'find sub{if(-f&&/^whatever/){say$File::Find::name;unlink}},"."' You might even be able to do 'find{...}"."' (no "sub" or ","), but I don't have perl on my phone to test that ;)
- a_gopher 10y agoperl -E 'sub x{say;for(<$_/*>){&x;unlink}};x for@ARGV' * perl -E 'push@ARGV,<$_/*>for@ARGV;say,unlink for@ARGV' *
- EvilTerran 10y agoIsn't that just "rm -rv *"? The original spec was to only delete files, not directories - and only those matching a given pattern, at that. Also, I think yours would go into an infinite spin if it met a symlink loop (say, "ln -s . foo") - File::Find is hardened against that kinda shenanigans.
- shanemhansen 10y agoMy favorite perl one liner is a globbed search and replace. It even has it's own website: http://perlpie.com/ http://perlpie.com/ perl -p -i -e 's/foo/bar/gi' ./*.txt
- scrame 10y agoThe -i switch takes an optional string that creates a backup of the file with that extension. To use your example (with zsh blobbing): perl -p -i.bak -e 's/foo/bar/gi' **/*.txt Recursively replaces foo with bar on every .txt file in a hierarchy and saves the original file with a .bak extension, along with the in-place edit in the original.
- jxy 10y agoWhat is the advantage of this over sed?
- JadeNB 10y ago> What is the advantage of this over sed? The same as for anything that could be done in the shell, but is done with a full-fledged programming language: when you discover you need to tweak it to accommodate an additional requirement, it's easy in Perl but hard in sed.
- nilved 10y agoIf that was the case you think you'd reach for literally any other language than Perl.
- untoreh 10y agoperl has the best regex, or one of the best, also it is the only other language other than python which is installed by default in common distros afaik
- aduitsis 10y agoIf you feel unproductive or uncomfortable with Perl, you should avoid it and use whatever language strikes your fancy. Many people however are extremely comfortable and productive with Perl, for a wide variety of reasons. It's really an awesome language that has proven its vast usefulness a long time ago.
- JadeNB 10y agoI like Krumins's explanations series even more than the bare one-liners: http://www.catonmat.net/search?q=Perl+one-liners+explained http://www.catonmat.net/search?q=Perl+one-liners+explained . (That said, a good context-free Perl one-liner can always be enjoyed on its mystifying own.) Note that there is a book with the one-liners (and, I assume, their explanations): https://www.nostarch.com/perloneliners https://www.nostarch.com/perloneliners . He also posted about Abigail's classic primality-testing one-liner at http://www.catonmat.net/blog/perl-regex-that-matches-prime-numbers http://www.catonmat.net/blog/perl-regex-that-matches-prime-n... .
- waynecochran 10y agoFor real? # Check if a number is a prime perl -lne '(1x$_) !~ /^1?$|^(11+?)\1+$/ && print "$_ is prime"'
- JadeNB 10y agoI guess you mean "For real?" as in "Is this really a primality test?" Yes, it is, and Krumins describes how it works in the post that I linked (http://www.catonmat.net/blog/perl-regex-that-matches-prime-numbers http://www.catonmat.net/blog/perl-regex-that-matches-prime-n...). Essentially, although it looks complicated, it's the simplest possible idea: it's just trying factorisations, with the `(11+?)` part being the factor, and the `\1+` part insisting that we repeat that factor. It is of course wildly inefficient, and limitations in the backtracking engine mean that it can give false positives for large numbers (http://zmievski.org/2010/08/the-prime-that-wasnt http://zmievski.org/2010/08/the-prime-that-wasnt, also linked from that post).
- labster 10y agoI prefer the Perl 6 version, it's self-documenting: perl6 -n -e 'say "$_ is prime" if (+$_).is-prime'
- wyclif 10y agoThe Perl One-Liners book is great. I learned so much from it. You don't even need to have done any real Perl programming to get a lot out of that book, but if you want to learn Perl it will help you as well.
- berntb 10y agoHere are a few quick and dirty I use for handling output of MySQL. (For serious stuff I include real CSV libraries in the one liner to quote correctly etc.) alias sqlcmdtocsv="perl -nE 'chomp; s/\\t/;/g; say \$_;'" alias sqlcmdtoperl="perl -MData::Dump=dump -nE 'chomp; @r=split(/\\t/); if (@titles == 0) { @titles=@r; next; } \$row={}; for(\$i=0; \$i < @r; \$i++) { \$row->{\$titles[\$i]} = \$r[\$i]; } push @rows, \$row; END { say dump \\@rows };'" # Quick and dirty for moving from the real DB to the test DB. # Use: mysql_generates_a_row | sqlcmdtoperl | dumptosqlinsert alias dumptosqlinsert="perl -E 'my \$txt; { local \$/; \$txt=<>; } my \$rows= eval \$txt; \$q=chr(39); for my \$r (@\$rows) { @cols=map { \$v=\$r->{\$_}; if (\$v eq \"NULL\") {\"\$_=NULL\"} else {\"\$_=\${q}\$v\$q\"} } keys %\$r; say join(\", \", @cols);}'" I have a bunch of aliases for conversions, to generate common SQL that dependend on parameters and so on.
- pre_action 10y agoI wrote the `ysql` Perl application for exactly this problem
- berntb 10y agoIt was faster than Googling. :-) But it would have been better to build off a well tested module as a basis for my set of tools, sigh. I could have used yaml as an intermediary. A favorite saying is from chemistry -- with a few weeks of hard work in the lab, you can save hours in the library...
- rektide 10y agoI liked this part of perl so much that I recently rewrote perl style substitution in Node.js. Used as an executable, it functions largely like perl -p -e: https://github.com/rektide/perls https://github.com/rektide/perls
- pmoriarty 10y agoI like to use "ped" (Lee Eaken's "sed done right" rewrite in perl, which allows in-place editing): http://www.cpan.org/authors/id/L/LE/LEAKIN/ped-1.2 http://www.cpan.org/authors/id/L/LE/LEAKIN/ped-1.2 https://jakobi.github.io/script-archive-doc/cli.list.grep/00_LISTPROCESSING.html https://jakobi.github.io/script-archive-doc/cli.list.grep/00...
- scrame 10y agocat FILE | perl -lne 'm|(REGEX)|&&print$1' Pays for itself pretty quickly. I default to pipes for the delimiter so you don't have to escape file paths.
- btilly 10y agoAnd here is a dirty Perl joke. What does this command have to do with pussy? perl -penis . . . (It is an implementation of cat.)
- nanoojaboo 10y agoso 'perl -penis semen.txt' dumps what on the screen?
- vram22 10y agoWhile it's not in Perl (it uses grep, sed and awk), I like this Unix one-liner (mine) to kill a hanging Firefox process, not so much for the code but for the interesting comment thread that it resulted in on my blog - about Unix processes, zombies, etc. UNIX one-liner to kill a hanging Firefox process: http://jugad2.blogspot.in/2008/09/unix-one-liner-to-kill-hanging-firefox.html http://jugad2.blogspot.in/2008/09/unix-one-liner-to-kill-han...
- xorcist 10y agoI see you got this comment already, but still: Make a habit of using pkill instead of stuffing ps output to kill when you can. It's not everywhere, but it's on Linux/BSD/Solaris. (Avoid killall; that's unportable is a special way.) That's readable and avoids things like filtering out your greps.
- vram22 10y agoInteresting, didn't know of that reason for using pkill - thanks.
- shabble 10y agoThanks for the introduction to 'sed 1d', which is something I've somehow never come across and resorted to horrible head|tail hacks to strip fixed header lines off things.
- vram22 10y agoNP. You may know this, but there is also 'sed nq' where n is a number. E.g.: sed 15q file.txt which is like the 'head' command - prints the 1st 15 lines of file.txt and then stops.
- vacri 10y agoUse `xkill` (if you're using X). `xkill` in a terminal, then click on the window you want to kill. Boom. No need to type out a convoluted command.
- EvilTerran 10y agoA personal favourite of mine: perl -lp0e1 /proc/$pid/environ It relies on some fairly subtle interactions in perl's command-line processing, and I do enjoy how cunning that makes it feel. And it's actually useful, by way of being a lot easier to type (less moving your hands around the keyboard for odd bits of punctuation) than the "sensible" way to do it: tr '\0' '\n' < /proc/$pid/environ
- Gorgor 10y agoCould you explain that a bit more?
- EvilTerran 10y agoCertainly! That expands to: perl -l -p -0 -e 1 /proc/$pid/environ -l [octnum] is "automatic line-ending processing": it means the "input record separator" ($/, which defaults to "\n") is automatically stripped from the end of lines as they're read in; and the "output record separator" ($\, defaults to nothing), which is automatically appended to anything you print(), is set - to the character with the given octal code if specified, otherwise to the current value of $/. -p makes perl act like sed: the input (which can either be stdin or the files listed after the flags on the command-line) is read one-line-at-a-time into $_, and for each line, your program is run, then $_ is printed. -0 [octnum] sets the input record separator - and with no following digits, it gets set to the null character, "\0". -e [script] specifies the content of the script to run - in this case, "1", a very terse way of doing nothing. So: read each null-terminated "line", strip off the trailing null character, do nothing, then print it with a trailing newline. The sneaky part is the ordering of the flags: -l does { $\ = $/ }, -0 does { $/ = "\0" }, and they're processed in order - so if -0 appeared before -l, it wouldn't work, you'd wind up with both record separators set to "\0"; "-l0" would mean "-l with 0 as its parameter", ie { $\ = "\0" }, so I need to stick something else (-p) in between them if I want to squash everything into one argument without changing the meaning; and -e1 has to appear at the end, because -e eats the rest of the argument.
- teddyh 10y agoI prefer this, which is shorter than both of those: xargs -0n1 < /proc/$pid/environ
- yati 10y agoA very useful idiom I often use is $ foo |perl -nafe '<code>' Where <code> will be wrapped in a while(<>){ ... }. You can access the current line normally with $_ and either print out something everytime, keep state and then have an END block which can spit the final output. e.g., I was using something like the following today for getting some info on row sizes on a mysql table (untested): $ echo 'DESCRIBE table'|mysql |cut -f1 |tail -n +2 |perl -nafe 'chomp; push @fields, $_; END { print qq/SELECT MAX(row_size) from (SELECT/ . join(" + ", map { qq/CHAR_LENGTH($_)/ } @fields) . qq/ AS row_size FROM table)/; }'
- EvilTerran 10y agoIncidentally, you can pass a query as a parameter to `mysql` with -e, you don't need to pipe it in; and -N suppresses column headings, so you could use that instead of`tail`. ... also, you can pass -l (lowercase L) to `perl` to enable automatic line-end processing, which autochomps each line in the input (and sets the output record separator so echo() includes a trailing newline, not that it matters here). And FWIW you're not actually using -a (autosplit each line into @F) here - but you could use it instead of `cut`, and it does imply -n; you might not need -f either, unless you actually have a sitecustomize.pl for it to disable. So: $ mysql -Ne 'DESCRIBE table' | perl -ale 'push @fields, $F[0]; END { print qq/SELECT MAX(/ . join(" + ", map { qq/CHAR_LENGTH($_)/ } @fields) . qq/) FROM table/ }' (I could golf it further, but I think that covers the stuff you might actually find useful. I blame my perlmonks days...)
- yati 10y agoHa, nice. I must admit I just do `perl -nafe` almost out of muscle memory, without paying too much attention to what the options mean individually. Thanks for this :)
- ldoroud 10y agoMy favorite command when dealing with csv/txt files generated by Microsoft products: perl -p -e 's/\r/\n/g' Bad_Microsoft.csv Good_unix.csv
- Gorgor 10y agoDon't you end up duplicating every line break that way? I think it should be perl -p -e 's/\r//g' Bad_Microsoft.csv Good_unix.csv After all, Microsoft files usually end in a carriage return followed by a line break and not a bare carriage return, don't they?
- ldoroud 10y agoNot really or at least I haven't had that problem. It would be a problem if they used both \r and \n at the same time. in that case you can always do \r\n to \n or something like that.
- kazinator 10y agoMost of the basic text processing ones are shorter in and Awk and when they're not shorter, they are still clearer: no cryptic command line options, no gratuitous line noise: # Double space a file perl -pe '$\="\n"' perl -pe 'BEGIN { $\="\n" }' perl -pe '$_ .= "\n"' perl -pe 's/$/\n/' perl -nE 'say' awk 'BEGIN { ORS="\n\n" }' # output record separator awk 'print; print "\n"' awk '$0=$0"\n"' txr -e '(awk ((set rec `@rec\n`)))' # Awk macro in Lisp! # Double space a file, except the blank lines perl -pe '$_ .= "\n" unless /^$/' perl -pe '$_ .= "\n" if /\S/' awk 'BEGIN { ORS="\n\n" } /./' awk '/./ { print; print "\n" )' awk '/./&&$0=$0"\n"' txr -e '(awk (#/./ (set rec `@rec\n`) (prn)))' # Remove all consecutive blank lines, leaving just one perl -00 -pe '' perl -00pe0 awk -v RS= -v ORS="\n\n" 1 # RS=<blank> -> Awk paragraph mode txr -e '(awk (:set rs nil ors "\n\n") (t))' # Number all lines in a file perl -pe '$_ = "$. $_"' awk '{ print FNR, $0 }' txr -e '(awk (t (prn fnr rec)))' # Print the total number of lines in a file (emulate wc -l) perl -lne 'END { print $. }' awk 'END { print FNR }' # Find the total number of fields (words) on each line perl -alne 'print scalar @F' awk '{print NF}' # elides loop if cond/action clauses absent so (nil) needed txr -e '(awk (nil) (:end (prn fnr)))' # Print the last 10 lines of a file (emulate tail -10) perl -ne 'push @a, $_; @a = @a[@a-10..$#a]; END { print @a }' awk '{ ln[FNR%10]=$0 } END { for(i=FNR-9;i<=FNR;i++) if (i > 0) print ln[i%10] }' txr -e '(awk (:let l) (t (push rec l) (del [l 10])) (:end (tprint (nreverse l))))' txr -e '(awk (:let l) (t (set [l 10..10] (list rec)) (del [l 0..-10])) (:end (tprint l)))' # (real way) txr -t '[(get-lines) -10..:]' < in txr -t '(last (get-lines) 10)' < in
- MichaelMoser123 10y agoif you really need it then finding the one liner you need takes more time than writing it up yourself. Am i the only one who thinks so?
- berntb 10y agoI think the obvious counter argument is: You read them to learn. I learned a couple of perl flags in this discussion I had forgotten. Also, you get ideas about what you can do. And third, after reading through a collection like that, you can find stuff back by looking in an index.