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