nawk/ksh help


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting nawk/ksh help
# 1  
Old 03-06-2008
nawk/ksh help

Hello,

First of all, I am trying to duplicate the sum command using ksh/nawk


Lets assume the following algorithms work just fine and there is no calculation errors what so ever (which I doubt at this minute).


For now, I wanna make sure the script uses the BSD algorithim if -r is used and it uses the SysV algorthim if no option is used. Also, I have another problem is, how to get binary data in a form nawk can manipulate. I want to convert it to ASCII hex 1st using dhex -X . If you look at the script you will see I am using hex_to_dec nawk script later on.

I will post both the nawk/ksh and the original c file


Please bear with me, this is my 1st nawk/ksh script.

The Dhex mentioned above, here is its man page :
DHEX

NAME
dhex - dump in hex and ascii

SYNOPSIS
dhex [-ahuxX] [-s offset] [-l length] <file >output

DESCRIPTION
Dhex reads a file from the standard input, and dumps it on
the standard output. If no options are given, the ouput is in
hex and ascii format. If the -u option is specified, the
hex is output in upper case. If the -x option is specified, just
the hexadecimal portion is output. If the -X option is specified,
the hexadecimal portion is output in 160 column lines.

When used with chex and a text editor, dhex provides the ability
to patch any byte of any file. Simply convert the file to a hex
and ascii dump using dhex. Edit the bytes to be patched with
a text editor. Finally, create the patched file using chex.

OPTIONS
-a Format the output like the output of the disk array controller
debugger's dump command. Ignore the -u, -x, and -X options.

-h Print this manual page, and take no further action.

-l Print the specified number of bytes. The length can be specified
in decimal, or in hexadecimal with a 0x prefix. If the -l option
is not specified, the default is to dump until the end of file is
reached.

-s Seek offset bytes into the standard input before dumping.
Offset can be specified in decimal, or in hexadecimal with
a 0x prefix. The seek offset must be an even multiple of 16.
If it is not, it is rounded down to the nearest multiple.

-u Output the hexadecimal digits in upper case.

-x Output just the hexadecimal digits. This can be used to
prepare a file for an ASCII file transfer. When combined with
a sumcheck program such as crc or fletcher, a reliable file
transfer can be achieved.

-X Similar to -x, except it prints 160 hexadecimal digits per line.
This is often more convenient if the ASCII file transfer is to
be done using a mouse.

SEE ALSO
chex, crc, fletcher.





Code:
 

help()
{
    cat <<!
SUM2

NAME
    sum2 - print checksum and block count of a file

SYNOPSIS
    sum2 [-r] files
    sum2 -h

DESCRIPTION
    Sum2 calculates and prints a 16-bit checksum for the named
    files, and also prints the number of 512 byte blocks in each
    file. It is typically used to look for bad spots, or to
    validate files communicated over some transmission line.
    The option -r causes an alternate algorithm to be used in
    computing the checksum (namely, the BSD algorithm.)

EXAMPLES
    Suppose you have files named file1 and file2, and you want to compute
    the BSD checksum. Enter this command:

        sum2 -r file1 file2

    This might produce results similar to this:

        31409     1 file1
        05017     5 file2

SEE ALSO
    sum.
!
}


# main

status=0

h=0
r=0
x=0
lines=""
files=""
fileCount=0
checksum=0
ch=0
r=0
s=0


for parameter in $*
do
        letter=`echo x$parameter | cut -c2`
        if [ "$letter" = "-" ]
        then
                parameter=`echo x$parameter | cut -c3-`
                while [ "$parameter" != "" ]
                do
                        letter=`echo "x$parameter" | cut -c2`
                        parameter=`echo "x$parameter" | cut -c3-`

                        case "$letter" in
                        h)
                                h=1
                                previous=-h
                                ;;
                        r)
                                r=1
                                if [ "$parameter" = "" ]
                                then
                                        previous=-r
                                else
                                        lines=$parameter
                                        parameter=""
                                        previous=""
                                fi
                                ;;
                        x)
                                x=1
                                previous=-x
                                ;;
                        *)
                                echo "invalid option -$letter"
                                echo
                                status=1
                                ;;
                        esac
                done
        else
                case "$previous" in
                -r)
                        files="$files $parameter"
                        fileCount=`expr $fileCount + 1`
                        previous=""
                        ;;
                esac
        fi
done

if [ "$h" -eq 1 ]
then
        help
        exit 0
fi

if [ "$r" -eq 1 -a "$files" = "" ]
then
        echo "no filess specified"
        echo
        status=1
fi



if [ "$status" -ne 0 ]
then
        help
        exit 1
fi

if [ "$x" -eq 1 ]
then
        set -x
fi

# ----------------------------------------------------------------------------
     line = $0
     while (line != "" )
            {
            byte = substr(line,1,2)
            line = substr(line,3)

            value = hex_to_decimal(byte)

            if  (algorthim ==0 )
            {
                 # The BSD Algorthim

                 checksum = int(checksum / 2) + int ((checksum % 1) * 32768)    
                 checksum = checksum + ch
                 checksum = checksum % 65535
                 printf "%05d %5s", checksum
                 printf "%s", file
            }
            else
                 #The SysV Algorthim

                 r = ( s % 65535 ) + int(( s % 4294967295 ) / 65535)
                 checksum = (r % 65535) + int(r/65535)

                 printf "%d %s", checksum
                 printf "%s", file

              }






# ------------Hex to Dec nawk script-------------------------------------------
  function decimal_to_hex(decimal)
{
        hex_value = ""

        if (decimal == 0)
        {
                hex_value = "0"
        }
        else
        {
                while (decimal != 0)
                {
                        new_decimal = int(decimal / 16)
                        digit = decimal - (new_decimal * 16)

                        if (digit == 10)
                        {
                                digit = "a"
                        }
                        if (digit == 11)
                        {
                                digit = "b"
                        }
                        if (digit == 12)
                        {
                                digit = "c"
                        }
                        if (digit == 13)
                        {
                                digit = "d"
                        }
                        if (digit == 14)
                        {
                                digit = "e"
                        }
                        if (digit == 15)
                        {
                                digit = "f"
                        }

                        hex_value = digit""hex_value

                        decimal = new_decimal
                }
        }
        return hex_value
}

function hex_to_decimal(hex)
{
        decimal_value = 0

        ln = length(hex)

        for (column = 1; column <= ln; column++)
        {
                hex_digit = substr(hex, column, 1)
                digit_value = 0

                if (hex_digit >= "0" && hex_digit <= "9")
                {
                        digit_value = hex_digit
                }
                else
                {
                        if (hex_digit == "a")
                        {
                                digit_value = 10
                        }
                        if (hex_digit == "b")
                        {
                                digit_value = 11
                        }
                        if (hex_digit == "c")
                        {
                                digit_value = 12
                        }
                        if (hex_digit == "d")
                        {
                                digit_value = 13
                        }
                        if (hex_digit == "e")
                        {
                                digit_value = 14
                        }
                        if (hex_digit == "f")
                        {
                                digit_value = 15
                        }
                }

                decimal_value = (decimal_value * 16) + digit_value
        }
        return decimal_value
}

function hex_and(operand1, operand2)
{
        value = 0

        len = length(operand1)
        if (len < length(operand2))
        {
                len = length(operand2)
        }

        decimal1 = hex_to_decimal(operand1)
        decimal2 = hex_to_decimal(operand2)

        factor = 1

        while (decimal1)
        {
                digit1 = decimal1 % 2
                digit2 = decimal2 % 2

                if ((digit1 == 1) && (digit2 == 1))
                {
                        digit3 = 1
                }
                else
                {
                        digit3 = 0
                }

                value = value + (digit3 * factor)

                decimal1 = int(decimal1 / 2)
                decimal2 = int(decimal2 / 2)
                factor *= 2
        }
        value = decimal_to_hex(value)
        format_string = sprintf("0x%%0%ss", len)
        value = sprintf(format_string, value) ""
        return value ""
}



# --------------------------------------------------------------------------










 -------

/* sum -- checksum and count the blocks in a file
   Copyright (C) 86, 89, 91, 1995-2002, 2004, 2005 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Like BSD sum or SysV sum -r, except like SysV sum if -s option is given. */

/* Written by Kayvan Aghaiepour and David MacKenzie. */

#include <config.h>

#include <stdio.h>
#include <sys/types.h>
#include <getopt.h>
#include "system.h"
#include "error.h"
#include "human.h"
#include "safe-read.h"

/* The official name of this program (e.g., no `g' prefix).  */
#define PROGRAM_NAME "sum"

#define AUTHORS "Kayvan Aghaiepour", "David MacKenzie"

/* The name this program was run with. */
char *program_name;

/* True if any of the files read were the standard input. */
static bool have_read_stdin;

static struct option const longopts[] =
{
  {"sysv", no_argument, NULL, 's'},
  {GETOPT_HELP_OPTION_DECL},
  {GETOPT_VERSION_OPTION_DECL},
  {NULL, 0, NULL, 0}
};

void
usage (int status)
{
  if (status != EXIT_SUCCESS)
    fprintf (stderr, _("Try `%s --help' for more information.\n"),
             program_name);
  else
    {
      printf (_("\
Usage: %s [OPTION]... [FILE]...\n\
"),
              program_name);
      fputs (_("\
Print checksum and block counts for each FILE.\n\
\n\
  -r              defeat -s, use BSD sum algorithm, use 1K blocks\n\
  -s, --sysv      use System V sum algorithm, use 512 bytes blocks\n\
"), stdout);
      fputs (HELP_OPTION_DESCRIPTION, stdout);
      fputs (VERSION_OPTION_DESCRIPTION, stdout);
      fputs (_("\
\n\
With no FILE, or when FILE is -, read standard input.\n\
"), stdout);
      emit_bug_reporting_address ();
    }
  exit (status);
}

/* Calculate and print the rotated checksum and the size in 1K blocks
   of file FILE, or of the standard input if FILE is "-".
   If PRINT_NAME is >1, print FILE next to the checksum and size.
   The checksum varies depending on sizeof (int).
   Return true if successful.  */

static bool
bsd_sum_file (const char *file, int print_name)
{
  FILE *fp;
  int checksum = 0;    /* The checksum mod 2^16. */
  uintmax_t total_bytes = 0;   /* The number of bytes. */
  int ch;              /* Each character read. */
  char hbuf[LONGEST_HUMAN_READABLE + 1];
  bool is_stdin = STREQ (file, "-");

  if (is_stdin)
    {
      fp = stdin;
      have_read_stdin = true;
      if (O_BINARY && ! isatty (STDIN_FILENO))
        freopen (NULL, "rb", stdin);
    }
  else
    {
      fp = fopen (file, (O_BINARY ? "rb" : "r"));
      if (fp == NULL)
        {
          error (0, errno, "%s", file);
          return false;
        }
    }

  while ((ch = getc (fp)) != EOF)
    {
      total_bytes++;
      checksum = (checksum >> 1) + ((checksum & 1) << 15);
      checksum += ch;
      checksum &= 0xffff;      /* Keep it within bounds. */
    }

  if (ferror (fp))
    {
      error (0, errno, "%s", file);
      if (!is_stdin)
        fclose (fp);
      return false;
    }

  if (!is_stdin && fclose (fp) != 0)
    {
      error (0, errno, "%s", file);
      return false;
    }

  printf ("%05d %5s", checksum,
          human_readable (total_bytes, hbuf, human_ceiling, 1, 1024));
  if (print_name > 1)
    printf (" %s", file);
  putchar ('\n');

  return true;
}

/* Calculate and print the checksum and the size in 512-byte blocks
   of file FILE, or of the standard input if FILE is "-".
   If PRINT_NAME is >0, print FILE next to the checksum and size.
   Return true if successful.  */

static bool
sysv_sum_file (const char *file, int print_name)
{
  int fd;
  unsigned char buf[8192];
  uintmax_t total_bytes = 0;
  char hbuf[LONGEST_HUMAN_READABLE + 1];
  int r;
  int checksum;

  /* The sum of all the input bytes, modulo (UINT_MAX + 1).  */
  unsigned int s = 0;

  bool is_stdin = STREQ (file, "-");

  if (is_stdin)
    {
      fd = STDIN_FILENO;
      have_read_stdin = true;
      if (O_BINARY && ! isatty (STDIN_FILENO))
        freopen (NULL, "rb", stdin);
    }
  else
    {
      fd = open (file, O_RDONLY | O_BINARY);
      if (fd == -1)
        {
          error (0, errno, "%s", file);
          return false;
        }
    }

  while (1)
    {
      size_t i;
      size_t bytes_read = safe_read (fd, buf, sizeof buf);

      if (bytes_read == 0)
        break;

      if (bytes_read == SAFE_READ_ERROR)
        {
          error (0, errno, "%s", file);
          if (!is_stdin)
            close (fd);
          return false;
        }

      for (i = 0; i < bytes_read; i++)
        s += buf[i];
      total_bytes += bytes_read;
    }

  if (!is_stdin && close (fd) != 0)
    {
      error (0, errno, "%s", file);
      return false;
    }

  r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
  checksum = (r & 0xffff) + (r >> 16);

  printf ("%d %s", checksum,
          human_readable (total_bytes, hbuf, human_ceiling, 1, 512));
  if (print_name)
    printf (" %s", file);
  putchar ('\n');

  return true;
}

int
main (int argc, char **argv)
{
  bool ok;
  int optc;
  int files_given;
  bool (*sum_func) (const char *, int) = bsd_sum_file;

  initialize_main (&argc, &argv);
  program_name = argv[0];
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);

  atexit (close_stdout);

  have_read_stdin = false;

  while ((optc = getopt_long (argc, argv, "rs", longopts, NULL)) != -1)
    {
      switch (optc)
        {
        case 'r':              /* For SysV compatibility. */
          sum_func = bsd_sum_file;
          break;

        case 's':
          sum_func = sysv_sum_file;
          break;

        case_GETOPT_HELP_CHAR;

        case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);

        default:
          usage (EXIT_FAILURE);
        }
    }

  files_given = argc - optind;
  if (files_given <= 0)
    ok = sum_func ("-", files_given);
  else
    for (ok = true; optind < argc; optind++)
      ok &= sum_func (argv[optind], files_given);

  if (have_read_stdin && fclose (stdin) == EOF)
    error (EXIT_FAILURE, errno, "-");
  exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
}
------


Last edited by DeltaX; 03-06-2008 at 06:58 PM..
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Nawk Problem - nawk out of space in tostring on

Hi.. i am running nawk scripts on solaris system to get records of file1 not in file2 and find duplicate records in a while with the following scripts -compare nawk 'NR==FNR{a++;next;} !a {print"line"FNR $0}' file1 file2duplicate - nawk '{a++}END{for(i in a){if(a-1)print i,a}}' file1in the middle... (12 Replies)
Discussion started by: Abhiraj Singh
12 Replies

2. Shell Programming and Scripting

help with nawk

hi guys, I am writing a code and have stuck at one point. Inside nawk I am storing my desired variable a, I just need to find if a is present in an external file error.log or not. If yes, print something. grep or for loop not working properly inside nawk. Sample code provided. nawk ' BEGIN... (5 Replies)
Discussion started by: shekhar2010us
5 Replies

3. Shell Programming and Scripting

ksh/nawk help with if statement to choose between 2 files

Hi! I am having a bit of a problem with my script. There are two different date formats that may appear in a file, either Jul-12 or Jul--6. I tried to create an if statement that searches for one of the formats and if that doesn't exist searches for the other, however it doesn't seem to be... (3 Replies)
Discussion started by: ther2000
3 Replies

4. Shell Programming and Scripting

awk or nawk in ksh

I am trying to use either awk or nawk in ksh88 to grep the word "Reason" in multiple files and than print the lines that say "Reason" in a particular format that is different from how they would normally print. The original input is as follows: ... (10 Replies)
Discussion started by: ther2000
10 Replies

5. Shell Programming and Scripting

using nawk

help out with code. two files aaa bbb contains some records..output file xyz should be like this..see below i/p file:aaa 08350|60521|0000|505|0000|1555|000|NYCMT|Pd_1 |-11878 i/p file: bbb 60521|60510 o/p file :xyz 60510|08350|60521|0000|505|0000|1555|000|NYCMT|Pd_1 |-11878 (5 Replies)
Discussion started by: Diddy
5 Replies

6. Shell Programming and Scripting

Nesting - two nawk into one nawk

hi people; this is my two awk code: nawk '/cell+-/{r=(NF==8) ? $4FS$5FS$6 : NF==7 ? $4FS$5 : $4 ;c=split(r,rr);for (i=1;i<=c;i++){if(rr != "111111"){printf($3" %d ""\n",(i+3))}}printf("")}' /home/gc_sw/str.txt > /home/gc_sw/predwn.txt nawk -F'*' '{gsub(/ *$/,"")}$0=$1$($NF-2)'... (2 Replies)
Discussion started by: gc_sw
2 Replies

7. Shell Programming and Scripting

KSH script to run other ksh scripts and output it to a file and/or email

Hi I am new to this Scripting process and would like to know How can i write a ksh script that will call other ksh scripts and write the output to a file and/or email. For example ------- Script ABC ------- a.ksh b.ksh c.ksh I need to call all three scripts execute them and... (2 Replies)
Discussion started by: pacifican
2 Replies

8. UNIX for Dummies Questions & Answers

Arrays in nawk and ksh

I'm not confident at all on how arrays work. I want to know how to set arrays in ksh and in nawk (is there a difference??) if someone can show me some examples of both that will be great. Tried to look up on the net but was confusing me more. Any help would be appreciated. (2 Replies)
Discussion started by: Pablo_beezo
2 Replies

9. Shell Programming and Scripting

how to access values of awk/nawk variables outside the awk/nawk block?

i'm new to shell scripting and have a problem please help me in the script i have a nawk block which has a variable count nawk{ . . . count=count+1 print count } now i want to access the value of the count variable outside the awk block,like.. s=`expr count / m` (m is... (5 Replies)
Discussion started by: saniya
5 Replies

10. UNIX for Advanced & Expert Users

nawk use

I found a command who prints x lines before and after a line who contain a searched string in a text file. The command is : ------------------- nawk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r;print;c=a}b{r=$0}' b=2 a=4 s="string" file1 ...where "b" and "a" are the number of lines to print... (2 Replies)
Discussion started by: ctap
2 Replies
Login or Register to Ask a Question