Showing posts with label Shell. Show all posts
Showing posts with label Shell. Show all posts

Tuesday, January 1, 2013

Perl one-liners: File Extension Frequency

Perl Squirrel was curious about what types of files were on the Linux system.

Using a series of Linux commands to isolate just the extensions of each file, this output is piped to a Perl one-liner that stores in a hash, the file extension as the key and the occurrence count as the value.
The output is sorted by key (or file extension, alphabetical order).

This is all done as a one-liner.

Description and One-Liner Code:
## For all files, ## get basename of each file (meaning drop the directory portion of the string) ## except files starting with dot (meaning don't look at hidden files) ## except files containing comma (no strange files) ## awk uses period as field separator ( -F\. ) ## for lines that have more than 1 field (NF > 1 meaning there is at least one period in the file) ## print the last field $NF (meaning the file extension) ## Display unique extension and number of occurances find . -type f -print | xargs -I {} basename {} | grep -v "^\." | grep -v ',' | awk -F\. 'NF > 1 {print $NF}' | perl -e 'while(<>){chomp;$f{$_}++;}printf("%-40s %12i\n",$_,$f{$_}) foreach sort keys %f;'

Bonus:   Frequency counter for numeric values

To get frequency values for numeric values, you'll want to use a slightly different kind of sort when outputting the contents of the hash keys and values so that the keys display in numerical order not alphabetical order.

This is just an example to show the numeric sort.
In a long directory listing (ls -l), the 7th field contains the day of the month.
Lets get a frequency distribution of the day of the month for each item in the directory.

One-Liner Code:
ls -l | awk '$7 >= 1 {print $7}' | perl -e 'while(<>){chomp;$f{$_}++;}printf("%-40s %12i\n",$_,$f{$_}) foreach sort {$a<=>$b} keys %f;'

Happy New Year!!

Sunday, July 8, 2012

Shell script - Capture snippets from vi or Vim

Here is a utility that may be useful to people who use vi or Vim.
Perl Squirrel has a common tendency of collecting useful code samples and this tool enables that without too much time or effort.  The general idea is this... While editing code, highlight the code sample worth keeping and file it in a text file without leaving the vi or Vim environment. 

Here are the requirements for this utility:
  • You use 'vi' or 'Vim'
  • Create a subdirectory called "notes" under your home directory
  • Place the "snip.sh" utility in your personal 'bin' directory or somewhere in your PATH

Here is the code: (See Instructions in the code comments)
#!/bin/bash #Script: snip.sh #Purpose: Grab certain lines of text from the file # you are editing/viewing in vi/vim, # and append this snippet to a notes file. # #How to use in vi/vim session: # Position cursor on 1st line to save, press the letters # ma # Position cursor on last line to save, press the letters # mb # Capture the snippet to the default ~/notes/snippet.txt file # :'a,'b w !snip.sh # Or, Capture the snippet to a specified file ~/notes/favorite.txt # :'a,'b w !snip.sh favorite ["Optional Short description"] # #This code assumes you will store the snippets in a "notes" #subdirectory under your home directory. #Place this code in your personal bin directory, or in your PATH. #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SNIP=${1:-snippet} DESC="${2:-UNNAMED SNIPPET}" echo '#[SNIP]------------------------------------' >> ~/notes/${SNIP}.txt echo "#[SNIP] ${DESC} " >> ~/notes/${SNIP}.txt echo '#[SNIP]------------------------------------' >> ~/notes/${SNIP}.txt cat - >> ~/notes/${SNIP}.txt

Wednesday, November 30, 2011

Perl Power - Sequential Iteration in shell scripts

Lets say you want to process a bunch of files containing a numeric sequence like "inventory000297.txt" through "inventory000302.txt". You would like to print the following:

inventory000297.txt
inventory000298.txt
inventory000299.txt
inventory000300.txt
inventory000301.txt
inventory000302.txt

I did not see a simple way to do this using a plain shell script, but adding some perl is a different story...

for F in $(perl -e 'foreach $num (297 .. 302) {printf("%s%06i%s\n","inventory",$num,".txt");}')
do
    echo ${F}
done

Notes to keep in mind:
  • $( ) contains the perl one-liner that generates the output to print
  • The perl script is between the single quotes
  • The foreach loop block is within braces { }
  • The numerical range is in parenthesis ( 297 .. 302 ), change this as necessary
  • The printf has 3 format specifiers:

    %s corresponds with "inventory", change prefix as necessary

    %06i corresponds with $num, a fixed width 6 digit integer, change as necessary

    %s corresponds with the ".txt", change extension as necessary






Adjust the size of your sequence number - if 15 digits is needed you would use %015i for the format. That leading 0 says fill in with leading zeros on output to match the specified width.

Enjoy!