🖥️perl

➡️This is a command-line reference manual for commands and command combinations that you don’t use often enough to remember it. This cheatsheet explains the perl command with important options and switches using examples.

▁ ▂ ▃ ▄ ꧁ 🔴☠ COMMANDLINE-KUNGFU WITH CHEATSHEETS ☠🔴꧂▅ ▃ ▂ ▁

#                ██████╗ ███████╗██████╗ ██╗     
#                ██╔══██╗██╔════╝██╔══██╗██║     
#                ██████╔╝█████╗  ██████╔╝██║     
#                ██╔═══╝ ██╔══╝  ██╔══██╗██║     
#                ██║     ███████╗██║  ██║███████╗
#                ╚═╝     ╚══════╝╚═╝  ╚═╝╚══════╝
                

# The Perl 5 language interpreter.

# Parse and execute a Perl script:
perl script.pl

# Check syntax errors on a Perl script:
perl -c script.pl

# Parse and execute a perl statement:
perl -e perl_statement

# Import module before execution of a perl statement:
perl -Mmodule -e perl_statement

# Run a Perl script in debug mode, using perldebug:
perl -d script.pl

# Loo[p] over all lines of a file, editing them [i]n-place using a find/replace [e]xpression:
perl -p -i -e 's/find/replace/g' filename

# Run a find/replace expression on a file, saving the original file with a given extension:
perl -p -i'.old' -e 's/find/replace/g' filename

# See also:
#   Perl language cheat sheets at /perl/
#   list of pages:      /perl/:list
#   learn perl:         /perl/:learn
#   perl one-liners:    /perl/1line
#   search in pages:    /perl/~keyword
                                                
                                              
#==============================#
# CMD PERL
#==============================##==============================#
perl -pi.backup -e 's/\r//' foo.txt
#

perl -e 'sub a{@_[1-1]-@_[2-1]};\>print a(1-1,2-1)'
#

perl -e "s/^(\s*S[\s\S]*?)(\/\/\s*.*)$/\n\/\2\n\1" -p a.c>b.c
#

perl -wnle "/RE/ and print" filename
# Use Perl to grep for a regex RE

# The good: Many functions take regex arguments
# The bad: Limited features compared to PCRE
# The ugly: \|, \(, \), \{, \}

# Summarizing ed(1) movement commands
	{n} line #n
	+{n} n lines down
	-{n} n lines up
	/ search fwd
	? search back
	'a go to mark 'a

/(Ch|H|Kh)ann?[aeiu]kk?ah?/
# Regular expression for various spellings of Hanukkah 

perl -MMIME::Base64 -e 'print encode_base64("john\0john\0passwd")';
am9obgBqb2huAHBhc3N3ZA==

#=======================================================================================================
# 1. PERL ONE-LINERS
#=======================================================================================================

grep -in WORD FILE* | perl -ne 'if (/(.*):(\d*):\s*(.*)\s*/) { print $1, " " x (20 - length $1), " ", "0" x (5 - length $2), $2, "   $3\n"}'
# Display Table of WORD in FILE* - Displays all occurrences of WORD in the FILE*(s), formatting as a table with filename, line number and line text. - Simple example for short filenames.  Seems to cause trouble in Windows command line

egrep -in '(Alabama|"AL")' *.asp | perl -ne 'if (/(.*):(\d*):\s*(.*)\s*/) { print $1, " " x (50 - length $1), " ", "0" x (5 - length $2), $2, "   $3\n"}'
# Display Table of WORD in FILE* - Displays all occurrences of WORD in the FILE*(s), formatting as a table with filename, line number and line text. - More complex example using egrep and assuming longer filenames (note the '50' in the spaces computation) - Also seems to cause trouble in Windows command line.

# Text Trimming and Processing
#-----------------------------------------------------------------------

cat myfile | perl -ne 'if (/^\s*(.*?)\s*$/s) { print "${1}\n" }' 
# Trim excess blanks from beginning to end of line. A Cygwin creature. - seems less efficient in practice

perl -ne 'if (/^\s*(.*?)\s*$/s) { print "${1}\n" }' < temp.txt
# Trim excess blanks from beginning to end of line. - Don't forget the tr command! Not that we have use right now...

# Infinite "music"
perl -e 'use bytes; for($t=0;;$t++){ print chr($t*(($t>>13|$t>>8)&30&$t>>4)); }' | play -t raw -b8 -r8k -e un - vol 0.5

# File/Directory one liners
#-----------------------------------------------------------------------
ls -R					
# Recursively list contents of subdirectories

ls -lAF | perl -e 'while (<>) { next if /^dt/; $sum += (split)[4] } print "$sum\n"'
# Find the sum of the sizes of the non-directory files in a directory

ls | xargs perl -e '@ARGV = grep( -d $_ , @ARGV); print "@ARGV\n"'	
# Different formats for the subdirectories of just this directory

ls | xargs perl -e '@ARGV = grep( -d $_ , @ARGV); while($dir = shift @ARGV) { print "$dir\n" }'
# Different formats for the subdirectories of just this directory

# Path Parsing One Liners
#=======================================================================================================
# Can't use EXPR because it only matches at the beginning of a line.
if echo $PATH | grep -q "Program" ; then echo "present"; else echo "absent"; fi
if echo $PATH | grep -q "\." ; then echo ". present"; else export PATH=".:$PATH"; echo "added . to path";  fi
perl -e "print \"$PATH\" =~ /Program/"	# not good for testing

if [ "$fram" ]; then echo "found a fram"; else echo "no fram here"; fi
# See if a variable exists

perl -e "print join qq(\n), split /;/, '%CLASSPATH%' "
# Use Perl to do the same thing - to print all the variable names on one line - note this can futz up some pathnames

perl -e "foreach (split ';', '%CLASSPATH%') { print; print qq(\n) }"
# Use Perl to do the same thing - to print all the variable names on one line - note this can futz up some pathnames

perl -e 'use bytes; for($t=0;;$t++){ print chr($t*(($t>>13|$t>>8)&30&$t>>4)); }' | play -t raw -b8 -r8k -e un - vol 0.5 
# Infinite "music"

perl -ne 'print if /start_pattern/../stop_pattern/' file.txt
# Display a block of text: multi-line grep with perl
# 		-n reads input, line by line, in a loop sending to $_ Equivalent to while () { mycode } 
# 		-e execute the following quoted string (i.e. do the following on the same line as the perl command) the elipses .. operator behaves like a range, remembering the state from line to line.

#=======================================================================================================
# DOS Fu One Liners
#=======================================================================================================
for /F %i IN (lines.txt) DO echo %i
# DOS/Windows Equivalents of Common UNIX Commands - Iterate through all the lines in a file, doing something

prompt $P $C$D$T$F: $_$+$G$S
# DOS/Windows Prompt

perl -e '$n=0;@a=(a..z,A..Z,0..9," ","!");$A=2**6;$H="3300151524624962270817190703002462370017172463";while($n<length $H){$M.=$a[substr($H,$n,2)];$n+=2};$M=~s/X/${A}th/;print "$M\n"'

perl -e '$n=0;@TimToady=(a..z,A..Z,0..9," ","!");$A=2**6;$H="3300151524624962270817190703002462370017172463";while($n<length $H){$M.=$TimToady[substr($H,$n,2)];$n+=2};$M=~s/X/${A}th/;print "$M\n"' # Thought of a better way to do this in this medium.

# Rename all files in the current directory by capitalizing the first letter of every word in the filenames
ls | perl -ne 'chomp; $f=$_; tr/A-Z/a-z/; s/(?<![.'"'"'])\b\w/\u$&/g; print qq{mv "$f" "$_"\n}'
# Explanation: 
    # When you pipe something to perl -ne, each input line is substituted into the $_ variable. The chomp, tr///, s/// perl functions in the above command all operate on the $_ variable by default.
    # The tr/A-Z/a-z/ will convert all letters to lowercase.
    # The regular expression pattern (?<![.'])\b\w matches any word character that follows a non-word character except a dot or a single quote.
    # The messy-looking '"'"' in the middle of the regex pattern is not a typo, but necessary for inserting a single quote into the pattern. (The first single quote # closes the single quote that started the perl command, followed by a single quote enclosed within double quotes, followed by another single quote to continue the perl command.) We could have used double quotes to enclose the perl command, but then we would have to escape all the dollar signs which would make everything less readable.
    # In the replacement string $& is the letter that was matched, and by putting \u in front it will be converted to uppercase.
    # qq{} in perl works like double quotes, and can make things easier to read, like in this case above when we want to include double quotes within the string to be quoted.
    # After the conversions we print a correctly escaped mv command. Pipe this to bash to really execute the rename with | sh.
# Limitations: The above command will not work for files with double quotes in the name, and possibly other corner cases.

# Generate a sequence of numbers
perl -e 'print "$_\n" for (1..10);'
# Explanation: Print the number with newline character which could be replaced by any char.

    
   

# Shuffle lines
... | perl -MList::Util=shuffle -e 'print shuffle <>;'

# Explanation: Sorting lines is easy: everybody knows the sort command. But what if you want to do the other way around? The above perl one-liner does just that:
    # -MList::Util=shuffle load the shuffle function from the List::Util package
    # -e '...' execute Perl command
    # print shuffle <> call List::Util::shuffle for the lines coming from standard input, read by <>

## Related one-liners

# Shuffle lines
... | perl -MList::Util -e 'print List::Util::shuffle <>'

# Explanation: Sorting lines is easy: everybody knows the sort command. But what if you want to do the other way around? The above perl one-liner does just that:
    # -MList::Util load the List::Util module (as if doing use List::Util inside a Perl script)
    # -e '...' execute Perl command
    # print List::Util::shuffle <> call List::Util::shuffle for the lines coming from standard input, read by <>
# Another way would be sort -R if your version supports that (GNU, as opposed to BSD). In BSD systems you can install coreutils and try gsort -R instead. (For eample on OSX, using MacPorts: sudo port install coreutils.)

# Group count sort a log file
A=$(FILE=/var/log/myfile.log; cat $FILE | perl -p -e 's/.*,([A-Z]+)[\:\+].*/$1/g' | sort -u | while read LINE; do grep "$LINE" $FILE | wc -l | perl -p -e 's/[^0-9]+//g'; echo -e "\t$LINE"; done;);echo "$A"|sort -nr
# Explanation: 
    # SQL: SELECT COUNT(x), x FROM y GROUP BY x ORDER BY count DESC;
    # BASH: a temp var for the last sort: $A=$(the file you want: FILE=/var/log/myfile.log
    # dump the file to a stream: cat $FILE |
    # cut out the bits you want to count: perl -p -e 's/.*,([A-Z]+)[\:\+].*/$1/g' |
    # get a unique list: sort -u |
    # for each line/value in the stream do stuff: while read LINE; do
    # dump all lines matching the current value to an inner stream: grep "$LINE" $FILE |
    # count them: wc -l |
    # clean up the output of wc and drop the value on stdout: perl -p -e 's/[^0-9]+//g';
    # drop the current value to stdout: echo -e "\t$LINE";
    # finish per value operations on the outer stream: done;
    # finish output to the temp var: );
    # dump the temp var to a pipe: echo "$A" |
    # sort the list numerically in reverse: sort -nr

# Explanation: Knowing the octal, hexadecimal or decimal code of the ASCII character set can be handy at times. In the past, too often I did things like:
perl -e 'for my $n (1 .. 255) { print $n, chr($n), $n, "\n"; }'
	# ... when a simple man ascii would have done the trick...
	# On a related note, these all print the letter "A":
        # echo -e '\0101'
        # printf '\101'
        # printf '\x41'
        # perl -e 'print "\x41"'

# Calculate an h index from an EndNote export
MAX=$(NUM=1;cat author.xml |perl -p -e 's/(Times Cited)/\n$1/g'|grep "Times Cited" |perl -p -e 's/^Times Cited:([0-9]*).*$/$1/g'|sort -nr | while read LINE; do if [ $LINE -ge $NUM ]; then echo "$NUM"; fi; NUM=$[$NUM+1]; done;); echo "$MAX"|tail -1
        # Explanation: EndNote?! I know but sometimes we have windows users as friends

# Rename files with numeric padding
perl -e 'for (@ARGV) { $o = $_; s/\d+/sprintf("%04d", $&)/e; print qq{mv "$o" "$_"\n}}'
# Explanation: Basically a one-liner perl script. Specify the files to rename as command line parameters, for example:
perl -e '.....' file1.jpg file2.jpg
# In this example the files will be renamed to file0001.jpg and file0002.jpg, respectively. The script does not actually rename anything. It only prints the shell commands to execute that would perform the renaming. This way you can check first that the script would do, and if you want to actually do it, then pipe the output to sh like this:
perl -e '.....' file1.jpg file2.jpg | sh
# what is happening in the one-liner perl script:
    # for (@ARGV) { ... } is a loop, where each command line argument is substituted into the auto-variable $_.
    # $o = $_ :: save the original filename
    # s/// :: perform pattern matching and replacement on $_
    # print qq{...} :: print the mv command, with correctly quoted arguments
# Limitations: The script does not cover all corner cases. For example it will not work with files that have double-quotes in their names. In any case, it is safe to review the output of the script first before piping it to sh.

# Counting the number of commas in CSV format
perl -ne 'print tr/,//, "\n"' < file.csv | sort -u
# Explanation: Sometimes I need to know if a CSV file has the right number of columns, and how many columns there are. The tr/// operator in perl is normally used to convert a set of characters to another set of characters, but when used in a scalar context like in this example, it returns the number of matches of the specified characters, in this case a comma. The perl command above prints the number of commas in every line of the input file. sort -u sorts this and outputs only the unique lines. If all lines in the CSV file have the same number of commas, there should be one line of output. The number of columns in the file is this number + 1.
# Limitations: This one-liner does not handle the more general case when the columns may have embedded commas within quotes. For that you would need a more sophisticated method. This simple version can still be very useful in many common cases.

Shuffle lines
... | perl -MList::Util -e 'print List::Util::shuffle <>'
# Explanation: Sorting lines is easy: everybody knows the sort command. But what if you want to do the other way around? The above perl one-liner does just that:
        # -MList::Util load the List::Util module (as if doing use List::Util inside a Perl script)
        # -e '...' execute Perl command
        # print List::Util::shuffle <> call List::Util::shuffle for the lines coming from standard input, read by <>
        # Another way would be sort -R if your version supports that (GNU, as opposed to BSD). In BSD systems you can install coreutils and try gsort -R instead. (For eample on OSX, using MacPorts: sudo port install coreutils.)

# Best method to organize massive word lists
# For simple deduplication of arrays you can use an associative array/hash. Simply use the word as the key and give it a value of true.  Enumerating the keys then gives you the deduplicated list of words.  If you want that list sorted then simply sort it afterwards.  Here's a quick Perl example:

#!/usr/bin/perl
use strict;
use warnings;

my %words;

while (my $line = <STDIN>) {
    chomp($line);
    $words{lc($line)} = 1;
}
print join("\n", sort keys %words);

#==============================##==============================#
# CMD PERL
#==============================##==============================#
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

  █║▌│║█║▌★ KALI ★ PARROT ★ DEBIAN 🔴 PENTESTING ★ HACKING ★ █║▌│║█║▌

              ██╗ ██╗ ██████╗  ██████╗ ██╗  ██╗███████╗██████╗
             ████████╗██╔══██╗██╔═══██╗╚██╗██╔╝██╔════╝██╔══██╗
             ╚██╔═██╔╝██║  ██║██║   ██║ ╚███╔╝ █████╗  ██║  ██║
             ████████╗██║  ██║██║   ██║ ██╔██╗ ██╔══╝  ██║  ██║
             ╚██╔═██╔╝██████╔╝╚██████╔╝██╔╝ ██╗███████╗██████╔╝
              ╚═╝ ╚═╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═════╝

               █║▌│║█║▌ WITH COMMANDLINE-KUNGFU POWER █║▌│║█║▌

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░