49. Generate and print the alphabet.复制代码 This one-liner prints all the letters from a to z as abcdefghijklmnopqrstuvwxyz. The letters are generated by the range operator ... The range operator, when used in the list context (which is forced here by print) on strings, uses the magical auto-increment algorithm that advances the string to the next character. So in this one-liner the auto-increment algorithm on the range a..z produces all the letters from a to z.
I really golfed this one-liner. If you used strict it would not work because of barewords a and z. Semantically more correct version is this:- perl -le 'print ("a".."z")'
复制代码 Remember that the range operator .. produced a list of values. If you wish, you may print them comma separated by setting the $, special variable:- perl -le '$, = ","; print ("a".."z")'
复制代码 There are many more special variables. Take a look at my special variable cheat sheet for a complete listing.
Syntactically more appealing is to use join to separate the list with a comma:- perl -le 'print join ",", ("a".."z")'
复制代码 Here the list a..z gets joined by a comma before printing.
50. Generate and print all the strings from "a" to "zz".- perl -le 'print ("a".."zz")'
复制代码 Here the range operator .. is used again. This time it does not stop at "z" as in the previous one-liner, but advances z by one-character producing "aa", then it keeps going, producing "ab", "ac", ..., until it hits "az". At this point it advances the string to "ba", continues with "bb", "bc", ..., until it reaches "zz".
Similarly, you may generate all strings from "aa" to "zz" by:- perl -le 'print "aa".."zz"'
复制代码 Here it goes like "aa", "ab", ..., "az", "ba", "bb", ..., "bz", "ca", ... "zz".
51. Create a hex lookup table.复制代码 Here the array @hex gets filled with values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and letters a, b, c, d, e, f.
You may use this array to convert a number (in variable $num) from decimal to hex using base conversion formula:- perl -le '$num = 255; @hex = (0..9, "a".."f"); while ($num) { $s = $hex[($num%16)&15].$s; $num = int $num/16 } print $s'
复制代码 Surely, much easier way to convert a number to hex is just using the printf function (or sprintf function) with %x format specifier. (The example above just illustrates a use of a hex lookup table that we created by using the range operator.)- perl -le '$hex = sprintf("%x", 255); print $hex'
复制代码 (See my Perl printf and sprintf format cheat sheet for all the format specifiers.)
To convert the number back from hex to dec use the hex function:- perl -le '$num = "ff"; print hex $num'
复制代码 The hex function takes a hex string (beginning with or without "0x") and converts it to decimal.
52. Generate a random 8 character password.- perl -le 'print map { ("a".."z")[rand 26] } 1..8'
复制代码 Here the map function executes ("a".."z")[rand 26] code 8 times (because it iterates over the dummy range 1..8). In each iteration the code chooses a random letter from the alphabet. When map is done iterating, it returns the generated list of characters and print function prints it out by concatenating all the characters together.
If you also wish to include numbers in the password, add 0..9 to the list of characters to choose from and change 26 to 36 as there are 36 different characters to choose from:- perl -le 'print map { ("a".."z", 0..9)[rand 36] } 1..8'
复制代码 If you need a longer password, change 1..8 to 1..20 to generate a 20 character long password.
53. Create a string of specific length.复制代码 Operator x is the repetition operator. This one-liner creates a string of 50 letters "a" and prints it.
If the repetition operator is used in list context, it creates a list (instead of scalar) with the given elements repeated:- perl -le '@list = (1,2)x20; print "@list"'
复制代码 This one liner creates a list of twenty repetitions of (1, 2) (it looks like (1, 2, 1, 2, 1, 2, ...)).
54. Create an array from a string.- @months = split ' ', "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec"
复制代码 Here the @months gets filled with values from the string containing month names. As each month name is separated by a space, the split function splits them and puts them in @months. This way $months[0] contains "Jan", $months[1] contains "Feb", ..., and $months[11] contains "Dec".
Another way to do the same is by using qw// operator:- @months = qw/Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec/
复制代码 The qw// operator takes a space separated string and creates an array with each word being an array element.
55. Create a string from an array.- @stuff = ("hello", 0..9, "world"); $string = join '-', @stuff
复制代码 Here the values in array @stuff get turned in a string $string that has them separated by a hyphen. Turning an array in a string was done by the join function that takes a separator and a list, and concatenates the items in the list in a single string, separated by the separator.
56. Find the numeric values for characters in the string.- perl -le 'print join ", ", map { ord } split //, "hello world"'
复制代码 This one-liner takes the string "hello world", splits it into a list of characters by split //, "hello world", then it maps the ord function onto each of the characters, which returns the numeric, native 8-bit encoding (like ASCII or EBCDIC) of the character. Finally all the numeric values get joined together by a comma and get printed out.
Another way to do the same is use the unpack function and specify C* as the unpacking template (C means unsigned character and * means as many characters there are):- perl -le 'print join ", ", unpack("C*", "hello world")'
复制代码 57. Convert a list of numeric ASCII values into a string.- perl -le '@ascii = (99, 111, 100, 105, 110, 103); print pack("C*", @ascii)'
复制代码 Just as we unpacked a string into a list of values with the C* template in the one-liner above, we can pack them back into a string.
Another way to do the same is use the chr function that takes the code point value and returns the corresponding character:- perl -le '@ascii = (99, 111, 100, 105, 110, 103); print map { chr } @ascii'
复制代码 Similar to one-liner #55 above, function chr gets mapped onto each value in the @ascii producing the characters.
58. Generate an array with odd numbers from 1 to 100.- perl -le '@odd = grep {$_ % 2 == 1} 1..100; print "@odd"'
复制代码 This one-liner generates an array of odd numbers from 1 to 99 (as 1, 3, 5, 7, 9, 11, ..., 99). It uses the grep function that evaluates the given code $_ % 2 == 1 for each element in the given list 1..100 and returns only the elements that had the code evaluate to true. In this case the code tests if the reminder of the number is 1. If it is, the number is odd and it has to be put in the @odd array.
Another way to write is by remembering that odd numbers have the low-bit set and testing this fact:- perl -le '@odd = grep { $_ & 1 } 1..100; print "@odd"'
复制代码 Expression $_ & 1 isolates the low-bit, and grep selects only the numbers with low-bit set (odd numbers).
See my explanation of bit-hacks for full explanation and other related bit-hacks.
59. Generate an array with even numbers from 1 to 100.- perl -le '@even = grep {$_ % 2 == 0} 1..100; print "@even"'
复制代码 This is almost the same as the previous one-liner, except the condition grep tests for is "is the number even (reminder dividing by 2 is zero)?"
60. Find the length of the string.- perl -le 'print length "one-liners are great"'
复制代码 Just for completeness, the length subroutine finds the length of the string.
61. Find the number of elements in an array.- perl -le '@array = ("a".."z"); print scalar @array'
复制代码 Evaluating an array in a scalar context returns the number of elements in it.
Another way to do the same is by adding one to the last index of the array:- perl -le '@array = ("a".."z"); print $#array + 1'
复制代码 Here $#array returns the last index in array @array. Since it's a number one less than the number of elements, we add 1 to the result to find the total number of elements in the array.
Have Fun!
转自:http://www.catonmat.net/blog/perl-one-liners-explained-part-four/ |