code4Nix | Extract code blocks with ease

Many times, I come across scenario, wherein I need to split given file into sections and write it into different files or process them dynamically, as and when those sections are found.

I did solve this problem, although I find it to be rather inefficient, so I though of rewriting and came up with following generic function, which could be used by anyone to work on scenarios like extract function blocks from shell/perl/python scripts, or extract diff block from git diff output, etc.

Function Specification

function fn__extrt_block {

  test $# -ne 2 && exit 1
  test -f $2 && fv_iputFile=$2 || exit 2

  mkdir -p ${fv_funcWorkDir} && cd ${fv_funcWorkDir}

  grep -n "${fv_srchPtrn}" ${fv_iputFile} | cut -d':' -f1 > outfile

This grep command helps in finding out the line number to mark the beginning of block, using which following while loop will extract separate blocks.

  while true
    echo $(head -2 outfile) | read LB UB
    test ! -z ${UB} && UB=`echo ${UB} - 1 | bc`

LB and UB represents the lower and upper bound of block, i.e. beginning and ending of specific block. For instance, if the outfile has contents like this;

1:Hi Varun

15:Hi Nischal

24:Hi Team

Every iteration, reads first two lines and assigns LB to 1, UB to 15. Next line of code, decrements UB by 1, so as to mark the end of block correctly.

    echo "${LB},${UB:-\$}p" > sed_scpt
    sed -n -f sed_scpt ${fv_iputFile} > file__${LB}_${UB:-$}

Once LB and UB are set, it becomes easy to extract block from input file using sed -n, as shown above. To continue iterating, it is important to keep removing first line, after every successful iteration.

    sed '1d' outfile > outfile.n
    mv outfile.n outfile

As this is an infinite loop, it is important to break the loop, once input file is completely processed.

    test ! -s outfile && break


Let us say, you generate diff between two git commits using following command;

$> git diff versOne versTwo > ~/output__versOne_versTwo.diff

Then, execute the earlier defined function as follows;

$> fn__extrt_block '^diff' ~/output__versOne_versTwo.diff

This will generate block-specific files, with pattern file__*

GitHub Gist Code Reference

Hope this helps.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s