Famous Perl One-Liners Explained, Part VI: Selective printing and deleting of lines - good coders code, great reuse |
Famous Perl One-Liners Explained, Part VI: Selective printing and deleting of lines Posted: 27 Apr 2011 10:13 AM PDT This is the sixth part of a nine-part article on famous Perl one-liners. In this part I will create various one-liners for selective printing and deleting of certain lines. See part one for introduction of the series. Famous Perl one-liners is my attempt to create "perl1line.txt" that is similar to "awk1line.txt" and "sed1line.txt" that have been so popular among Awk and Sed programmers and Linux sysadmins. The article on famous Perl one-liners will consist of nine parts:
The selective printing and selective deleting of certain lines is actually the same process. If you wish to delete certain lines, you just print the lines you're interested in. Or the other way around! For example, to delete all lines with even line numbers, print the odd lines, and to delete odd lines print the even lines. After I am done with the 8 parts of the article, I will release the whole article series as a pdf e-book! Please subscribe to my blog to be the first to get it! Here are today's one-liners: 82. Print the first line of a file (emulate head -1). perl -ne 'print; exit' This is the simplest one-liner so far. Here Perl reads in the first line into 83. Print the first 10 lines of a file (emulate head -10). perl -ne 'print if $. <= 10' This one-liner uses the This one liner can also be written the other way around without use of perl -ne '$. <= 10 && print' Here the 84. Print the last line of a file (emulate tail -1). perl -ne '$last = $_; END { print $last }' Printing the last line of the file is a bit tricker, because you always have to maintain the previous line in memory. In this one-liner we always save the current line in 85. Print the last 10 lines of a file (emulate tail -10). perl -ne 'push @a, $_; @a = @a[@a-10..$#a]; END { print @a }' Now this is tricky. Here we push each line to the Here is an example. Suppose 86. Print only lines that match a regular expression. perl -ne '/regex/ && print' Here 87. Print only lines that do not match a regular expression. perl -ne '!/regex/ && print' This is the same as the previous one-liner, except the regular expression match has been negated. So all the lines that don't match the regex get printed. 88. Print the line before a line that matches a regular expression. perl -ne '/regex/ && $last && print $last; $last = $_' In this one-liner every line gets saved to 89. Print the line after a line that matches a regular expression. perl -ne 'if ($p) { print; $p = 0 } $p++ if /regex/' Here we set the variable 90. Print lines that match regex AAA and regex BBB in any order. perl -ne '/AAA/ && /BBB/ && print' This one-liner is basically the same as one-liner #86 above. Here we test if a line matches two regular expressions instead of line. If a line matches both regexes, then it gets printed. 91. Print lines that don't match match regexes AAA and BBB. perl -ne '!/AAA/ && !/BBB/ && print' This one-liner is almost the same as one-liner #87. Here we test if a line doesn't match two regular expressions in any order. If it doesn't match 92. Print lines that match regex AAA followed by regex BBB followed by CCC. perl -ne '/AAA.*BBB.*CCC/ && print' Here we simply chain regexes AAA, BBB and CCC with 93. Print lines that are 80 chars or longer. perl -ne 'print if length >= 80' This one-liner prints all lines that are 80 chars or longer. In Perl you can sometimes omit the brackets perl -ne 'print if length < 80' This is the opposite of previous one-liner. It checks if the length of a line is less than 80 characters. 95. Print only line 13. perl -ne '$. == 13 && print && exit' As I explained in one-liner #83, the 96. Print all lines except line 27. perl -ne '$. != 27 && print' Just like in previous one-liner, we check if the current line is line 27, if it's not then we Another way to write the same is to reverse perl -ne 'print if $. != 27' 97. Print only lines 13, 19 and 67. perl -ne 'print if $. == 13 || $. == 19 || $. == 67' If you have Perl 5.10 or later then you can use the perl -ne 'print if int($.) ~~ (13, 19, 67)' The smart matching operator 98. Print all lines between two regexes (including lines that match regex). perl -ne 'print if /regex1/../regex2/' This one-liner uses the flip-flop operator, which becomes true when a line matches 99. Print all lines from line 17 to line 30. perl -ne 'print if $. >= 17 && $. <= 30' This one-liner is very simple to understand. The I just thought of another way to write it, perl -ne 'print if int($.) ~~ (17..30)' This is one-liner uses the Perl 5.10 (and later) smart matching operator You can write the same idea in older Perls as following, perl -ne 'print if grep { $_ == $. } 17..30' What happens here is 100. Print the longest line. perl -ne '$l = $_ if length($_) > length($l); END { print $l }' This one-liner keeps the longest line seen so far in the 101. Print the shortest line. perl -ne '$s = $_ if $. == 1; $s = $_ if length($_) < length($s); END { print $s }' This one-liner is the opposite of the previous one. But as we're finding the minimum and 102. Print all lines that contain a number. perl -ne 'print if /\d/' This one-liner uses a regular expression 103. Find all lines that contain only a number. perl -ne 'print if /^\d+$/' This one-liner is very similar to the previous one, but instead of matching a number anywhere on the line, it anchors the match to the beginning of the line, and to the end of the line. The regular expression 104. Print all lines that contain only characters. perl -ne 'print if /^[[:alpha:]]$/ This one-liner checks if the line contains only characters and if it does, it 105. Print every second line. perl -ne 'print if $. % 2' This one-liner prints first, third, 5th, 7th, etc, line. It does so because 106. Print every second line, starting the second line. perl -ne 'print if $. % 2 == 0' This one-liner is very similar to the previous one but except printing 1st, 3rd, 5th, etc, lines, it prints 2nd, 4th, 6th, etc, lines. It prints them because 107. Print all lines that repeat. perl -ne 'print if ++$a{$_} == 2' This one-liner keeps track of the lines it has seen so far and it also keeps the count of how many times it has seen the line before. If it sees the line the 2nd time, it prints it out because 108. Print all unique lines. perl -ne 'print unless $a{$_}++' Here the lines get printed only if the hash value Have Fun!Thanks for reading the article! The next part is going to be about various interesting, intriguing, silly and crazy regular expressions, because Perl is all about regular expressions. |
You are subscribed to email updates from good coders code, great reuse To stop receiving these emails, you may unsubscribe now. | Email delivery powered by Google |
Google Inc., 20 West Kinzie, Chicago IL USA 60610 |
No comments:
Post a Comment
Keep a civil tongue.