[net.sources] shell text manipulation progs

jimmy@rlvd.UUCP (Jimmy Aitken) (01/08/85)

I am posting this for a friend who is not on the net at the moment.  It
contains several programs which, when used in shell scripts, ease the task
of several string manipulation routines.  Mail any replies, flames etc. to
me and I will forward them.  The (non-E)mail address of the contributer is:

	Craig Wylie,
	c/o Dept. Computer Science
	University of Stirling
	Stirling
	FK9 4LA
	SCOTLAND   (That's Northern Britain to all you sassenachs!)

#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	format.1
#	left.c
#	right.c
#	mid.c
#	ins.c
#	del.c
#	index.c
#	rindex.c
#	con.c
#	len.c
echo sh: Extracting format.1
sed 's/^X//' << 'SHAR_EOF' > format.1
X.TH FORMAT 1 
X.SH NAME
Xleft, right, mid, index, rindex, ins, del, con, len
X.br
X.in +10
X\-  String operations available in shell
X.in
X.SH SYNOPSIS
X.B left
Xstring count
X.sp
X.B right
Xstring count
X.sp
X.B mid
Xstring position count
X.sp
X.B index
Xstring target
X.sp
X.B rindex
Xstring target
X.sp
X.B ins
Xstring insertion_string position
X.sp
X.B del
Xstring position count
X.sp
X.B con
Xstring1 string2
X.sp
X.B len
Xstring
X.SH DESCRIPTION
X.I Left
Xreturns a substring of string made up of the leftmost count characters.
XThe returned string is terminated by '\\0' and is followed by
Xa newline character.
XIf the value passed in count is greater than the number of characters in
Xthe string then the entire string is returned, it is not padded.
X.PP
X.I Right 
Xis similar to left in that it returns a substring of the string
Xargument, it returns the rightmost count characters from the string.
X.PP
X.I Mid
Xis similar to the application of
X.I right
Xthen
X.I left
Xas it returns a substring of the string argument that begins at
Xcharacter position and contains count characters.
XIf the start position of the substring is greater than the length of
Xthe string then nothing is returned, if the count plus the start
Xposition are greater 
Xthan the length of the string then the right portion of the string,
Xstarting at character `position' is returned. No padding is
Xcarried out.
X.PP
X.I Index
Xis used to return the leftmost occurrence of a string or character
Xwithin the target string. Index considers the first character in a
Xstring to be at character position zero.
X.PP
X.I Rindex
Xis exactly the same as index except that it finds the rightmost
Xoccurrence of the character or string.
X.PP
X.I Ins
Xis used to insert one string or character at a particular position
Xwithin another string.
XIf the position for the insertion is greater than the length of the
Xtarget string then the insertion is made at the end of the target string,
Xie. the two strings are concatenated.
X.PP
X.I Del
Xis used to remove a string of specified length from the string
Xstarting at the character specified in `position'.
XIf the start position is greater than the length of the string then
Xno alteration occurs and the original string is returned intact, if
Xhowever the start position falls within the string but the
Xstart position plus the count of the characters to be removed is
Xgreater than the length of the string then the leftmost characters
Xup to the start position are returned (as in left).
X.PP
X.I Con
Xstands for concatenate and will return the two string arguments passed to
Xit as a single string.
X.PP
X.I Len
Xwill return the length of the string argument passed to it.
X.SH "RETURN CODES"
X.ta 4 20
X.nf
X	CODE	MEANING
X.sp
X.ta 6 14
X	0	SUCCESSFUL
X	1	TARGET STRING NOT FOUND (Index and rindex)
X	2	INVALID COMMAND FORMAT
X.fi
X.SH EXAMPLES
X.PP
XThe following programs were hacked together to show how the programs
Xgiven above can be used from within shell scripts, no claims are made
Xfor them.
X.sp 2
X.in +15
Xtim
X.sp
Xmid "`date`" 11 8
X.in
X.PP
XThis program will only work if date returns output in the format:
X.sp
X.in +15
XSat Jan  5 15:15:46 GMT 1985
X.sp
X.in
XNotice that mid can be used here and cut can not, cut would treat the
Xdouble space between Jan and 5 as a separator followed by a field, however
Xif the date was Jan 15 then the double space is reduced to a single
Xspace so altering the number of fields in the output.
XThis highlights the main use of these programs, they can be used when
Xthe number of characters present is known, cut is better when the
Xnumber of fields are known.
X.sp
X.in +15
Xscanner
X.sp 2
X.nf
Xif test `left $1 1` = "-"
Xthen
X  length=`len $1`
X  i=1
X  while test $i -lt 6
X  do
X    echo `mid $1 $i 1` is set
X    i=`expr $i + 1`
X  done
Xelse
X  echo No flags set in first argument
Xfi
X.in
X.fi
X.PP
XIt must be said that this program is hideously slow, but try something
Xlike  scanner -hello, this should demonstrate its workings (and its speed).
X.sp 2
X.in +15
Xalarm
X.sp
X.nf
Xif test $# != 2
Xthen
X  echo "Usage: $0 Hour Minute"
Xelse
X  time=$1:$2:
X  da=`date`
X  dt=`mid "$da" 11 6`
X  if test $dt != $time
X  then
X    (sleep 50; alarm $1 $2) &
X  else
X    echo 
X    echo Alarm call
X    echo 
X  fi
Xfi
X.in
X.fi
X.PP
XThis final program is simply an alarm clock that runs in background,
Xtime is specified using the 24 hour clock and the program is accurate
Xto 30 seconds (on average, worst case 50 seconds).
X.SH AUTHOR
XCraig Wylie, University of Stirling (cww@sgcs).
SHAR_EOF
echo sh: Extracting left.c
sed 's/^X//' << 'SHAR_EOF' > left.c
X#include <stdio.h>
X/*				LEFT				*/
X
X/*	Returns leftmost substring of argv[1], length of substring in argv[2] */
Xchar *strcpy();
Xchar *strncpy();
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char res[];
X  int  count , length;
X  if (argc >= 4 || argc <= 2)
X  {
X    printf("Usage : %s string length\n",argv[0]);
X    exit(-2);
X  }
X  sscanf(argv[2],"%d",&length);
X  printf("%.*s\n",length,argv[1]);
X}
SHAR_EOF
echo sh: Extracting right.c
sed 's/^X//' << 'SHAR_EOF' > right.c
X#include <stdio.h>
X/*				RIGHT				*/
X
X/*	Returns the right substring of argv[1], length in argv[2] */
Xchar *strcpy();
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char *format;
X  int  count , length , index;
X  if (argc >= 4 || argc <= 2)
X  {
X    printf("Usage : %s string length\n",argv[0]);
X    exit(-2);
X  }
X  sscanf(argv[2],"%d",&length);
X  format = argv[1];
X  format += strlen(argv[1])-length;
X  printf("%s\n",format);
X}
SHAR_EOF
echo sh: Extracting mid.c
sed 's/^X//' << 'SHAR_EOF' > mid.c
X#include <stdio.h>
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char *format;
X  int  count,position ;
X  if (argc >= 5 || argc <= 3)
X  {
X    printf("Usage : %s string position width\n",argv[0]);
X    exit(-2);
X  }
X  sscanf(argv[2],"%d",&position);
X  sscanf(argv[3],"%d",&count);
X  format =argv[1]+position;
X  printf("%.*s\n",count,format);
X}
SHAR_EOF
echo sh: Extracting ins.c
sed 's/^X//' << 'SHAR_EOF' > ins.c
X#include <stdio.h>
X/*				INS				*/
X
X/*	Inserts argv[2] into argv[1] at position argv[3] and returns result */
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char *format;
X  int  count ;
X  if (argc >= 5 || argc <= 3)
X  {
X    printf("Usage : %s main_string insert_string position\n",argv[0]);
X    exit(-2);
X  }
X  sscanf(argv[3],"%d",&count);
X  if(count>strlen(argv[1]))count=strlen(argv[1]);
X  format = argv[1] + count;
X  strcat(argv[2],format);
X  printf("%.*s%s\n",count,argv[1],argv[2]);
X}
SHAR_EOF
echo sh: Extracting del.c
sed 's/^X//' << 'SHAR_EOF' > del.c
X#include <stdio.h>
X/*				DEL				*/
X
X/*	Deletes the substring from argv[1] that starts at argv[2] and is
X	argv[3] characters long. */
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char *format;
X  int  count,position ;
X  if (argc >= 5 || argc <= 3)
X  {
X    printf("Usage : %s string position number_to_delete\n",argv[0]);
X    exit(-2);
X  }
X  sscanf(argv[2],"%d",&position);
X  sscanf(argv[3],"%d",&count);
X  if(position>strlen(argv[1]))position=strlen(argv[1]);
X  if((position+count)>strlen(argv[1]))count=strlen(argv[1])-position;
X  format =argv[1]+count+position;
X  printf("%.*s%s\n",position,argv[1],format);
X}
SHAR_EOF
echo sh: Extracting index.c
sed 's/^X//' << 'SHAR_EOF' > index.c
X#include <stdio.h>
X/*			INDEX				*/
X
X/*	Returns the character position of the first occurrence of argv[2]
X	within argv[1]
X*/
X
X
Xindex(s, t) 		/* return index of t in s, -1 if none */
Xchar s[], t[];
X{
X  int i,j,k;
X
X  for (i=0;s[i] != '\0';i++)
X  {
X    for (j=i, k=0; t[k] != '\0' && s[j]==t[k]; j++,k++)
X      ;
X    if (t[k] == '\0') return (i);
X  }
X  return (-1);
X}
X
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{ int ind;
X  if (argc>=4 || argc<=2)
X  {
X    printf("Usage : %s string pattern\n",argv[0]);
X    exit(-2);
X  }
X  ind = index(argv[1],argv[2]);
X  if (ind!=-1) printf("%d\n",ind);
X  else 
X  {
X    printf("%s\n","");
X    exit(-1);
X  }
X}
SHAR_EOF
echo sh: Extracting rindex.c
sed 's/^X//' << 'SHAR_EOF' > rindex.c
X#include <stdio.h>
X/*				RINDEX				*/
X
X/*	Returns position of last occurence of argv[2] within argv[1] */
X
X
Xindex(s, t) 		/* return index of t in s, -1 if none */
Xchar s[], t[];
X{
X  int i,j,k;
X
X  for (i=strlen(s);i >= 0;i--)
X  {
X    for (j=i, k=0; t[k] != '\0' && s[j]==t[k]; j++,k++)
X      ;
X    if (t[k] == '\0') return (i);
X  }
X  return (-1);
X}
X
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{ int ind;
X  if (argc>=4 || argc<=2)
X  {
X    printf("Usage : %s string pattern\n",argv[0]);
X    exit(-2);
X  }
X  ind = index(argv[1],argv[2]);
X  if (ind!=-1) printf("%d\n",ind);
X  else 
X  {
X    printf("%s\n","");
X    exit(-1);
X  }
X}
SHAR_EOF
echo sh: Extracting con.c
sed 's/^X//' << 'SHAR_EOF' > con.c
X#include <stdio.h>
Xchar *strcat();
X/*				CON				*/
X
X/*	concatenates argv[1] and argv[2] and prints the result */
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  if (argc >= 4 || argc <= 2)
X  {
X    printf("Usage : %s string1 string2\n",argv[0]);
X    exit(-2);
X  }
X  strcat(argv[1],argv[2]);
X  printf("%s\n",argv[1]);
X}
SHAR_EOF
echo sh: Extracting len.c
sed 's/^X//' << 'SHAR_EOF' > len.c
X#include <stdio.h>
X/*				LEN				*/
X
X/*	Returns length of string in argv[1] */
X
X
Xmain (argc,argv)
Xint argc;
Xchar **argv;
X{
X  char res[];
X  if (argc >= 3 || argc <= 1)
X  {
X    printf("Usage : %s string\n",argv[0]);
X    exit(-2);
X  }
X  printf("%d\n",strlen(argv[1]));
X}
SHAR_EOF
exit
-- 

--
Jimmy Aitken,	Rutherford Appleton Laboratory
		S. E. R. C.
		Chilton, Didcot, OXON OX11 0QX
		England

		+44 235 446555

		..!mcvax!ukc!rlvd!jimmy