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
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);
}
------
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)
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)
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)
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)
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)
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)
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)
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)
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)