mh@killer.UUCP (04/05/87)
[] Speaking of mail merging, here's an older one. #!/bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # # Wrapped by mh on Sat Apr 4 19:16:26 CST 1987 # Contents: letter list mmerge.c mmerge.doc echo x - letter sed 's/^XX//' > "letter" <<'@//E*O*F letter//' XX3 August 1985 XX@1 XX@2 XX@3 XX@4 XX@5 XXDear @6, XX The current offer is rejected, please resubmit in 90 days. XXSincerely, XXJoe Blow Industries XXNew York @//E*O*F letter// chmod u=rw,g=r,o=r letter echo x - list sed 's/^XX//' > "list" <<'@//E*O*F list//' XX.XXX XXMr. Corncob Bueller XXFinancial Wizard XX301 N. Pork Chop XXDallas, TX 10101 XXMr. Bueller XX.XXX XXMrs. G. Ricardo XXPlaintiff XX1441 E. 3rd St. XXDallas, TX 01010 XXMrs. Ricardo @//E*O*F list// chmod u=rw,g=r,o=r list echo x - mmerge.c sed 's/^XX//' > "mmerge.c" <<'@//E*O*F mmerge.c//' XX/* XX mmerge.c XX Matthew Rapaport, July 1985 XX Scaetrix Co, 222 Fifth St, Petaluma, CA, 94952 XX Compuserve 70371,255 XX This version works with C/80(tm) v3.0 XX and UniFLEX(tm) v2.0 XX This program merges a list of names to a letter XX Sends impersonal mail to prospective customers XX*/ XX#ifdef CPM XX#include "a:stdio.h" XX#include "a:printf.h" XX#else XX#include <stdio.h> XX#endif XX#define FALSE 0 XX#define TRUE ~FALSE XX#define MAXLINE 40 XXstruct record { XX char testln[MAXLINE]; XX char nameln[MAXLINE]; XX char titlln[MAXLINE]; XX char addrln[MAXLINE]; XX char cityln[MAXLINE]; XX char auxone[MAXLINE]; XX char auxtwo[MAXLINE]; XX} currec; XXmain(argc,argv) XXint argc; XXchar *argv[]; XX{ XX#ifdef CPM XX FILE list, letter; XX#else XX FILE *list, *letter; XX#endif XX char *fgets(); XX if (argc != 3) { XX fprintf(stderr,"\nusage: mmerge listfile letterfile\n"); XX exit(0); XX } XX if ((list = fopen(argv[1],"r")) == 0) { XX fprintf(stderr,"\nCan't open list file %s\n",argv[1]); XX exit(0); XX } XX if ((letter = fopen(argv[2],"r")) == 0) { XX fprintf(stderr,"\nCan't open letter file %s\n",argv[2]); XX exit(0); XX } XX for(;;) { XX if ((fgets(currec.testln,MAXLINE,list)) == 0) XX break; XX fgets(currec.nameln,MAXLINE,list); XX fgets(currec.titlln,MAXLINE,list); XX fgets(currec.addrln,MAXLINE,list); XX fgets(currec.cityln,MAXLINE,list); XX fgets(currec.auxone,MAXLINE,list); XX fgets(currec.auxtwo,MAXLINE,list); XX mergit(&currec,letter); XX } XX fclose(list); XX fclose(letter); XX} XXmergit(ptr,letter) XXstruct record *ptr; XX#ifdef CPM XXFILE letter; XX#else XXFILE *letter; XX#endif XX{ XX int i, letchar; XX char d, flag, string[MAXLINE]; XX while ((letchar = getc(letter)) != EOF) { XX if (letchar == '@') { XX d = letchar; XX letchar = getc(letter); XX flag = FALSE; XX switch (letchar) { XX case '1': XX strcpy(string,ptr->nameln); XX break; XX case '2': XX strcpy(string,ptr->titlln); XX break; XX case '3': XX strcpy(string,ptr->addrln); XX break; XX case '4': XX strcpy(string,ptr->cityln); XX break; XX case '5': XX strcpy(string,ptr->auxone); XX break; XX case '6': XX strcpy(string,ptr->auxtwo); XX break; XX/* if the next char was not a number 1 - 6, print the '@' and what ever */ XX/* followed it on the standard output */ XX default: XX flag = TRUE; XX putchar(d); XX putchar(letchar); XX } XX if (!flag) XX for(i = 0; string[i] != '\n'; i++) XX putchar(string[i]); XX } XX else /* no '@' so just put the char to stdout */ XX putchar(letchar); XX } XX putchar('\f'); /* form feed the printer */ XX#ifdef CPM XX seek(letter,0,0); /* rewind letter file to beginning */ XX#else XX rewind(letter); XX#endif XX} XX#ifdef CPM XXchar * XXfgets(buf,size,fp) /* missing in c/80 library */ XXFILE fp; XXint size; XXchar *buf; XX{ XX int c; XX char *cs; XX cs = buf; XX while (--size > 0 && (c = getc(fp)) != EOF) XX if ((*cs++ = c) == '\n') XX break; XX *cs = '\0'; XX return((c == EOF && cs == buf) ? NULL : buf); XX} XX#endif @//E*O*F mmerge.c// chmod u=rw,g=r,o=r mmerge.c echo x - mmerge.doc sed 's/^XX//' > "mmerge.doc" <<'@//E*O*F mmerge.doc//' XXAugust 3, 1985 XXMailmerge anyone? Here is a short program that merges a list of XXnames, titles, addresses, etc. with documents specially formatted XXto receive the list. The program takes the data to be merged XXfrom a list file consisting of individual lines seperated by XXnewlines. There must be seven such lines in each record, XXwith the first being a record separator line. I use .XXX as my XXseparator line (I'm going to build a sorting function around XXthis), but anything will do. The list thus has room for name, XXtitle, address, city-state-zip, and two auxiliary lines that XXmight hold some other information. The list file looks like this: XXSEPARATOR LINE XXname XXtitle XXaddress XXcity, state zipcode XXaux 1 XXaux 2 XXSEPARATOR LINE XXname XXetc... XXNote that even if aux 1 and aux 2 are not used, there must at XXleast be blank lines in their place. The document to be merged XXcan be any kind of text. The function mergit() reads the XXdocument character by character until it encounters an '@' XXsymbol. It then saves that character and reads the next XXcharacter. If this next character is a number in the range 1 - XX6, the appropriate line from the list record will be substituted XXfor the '@1' or '@2' etc. If the character immediately following XXthe '@' is not a number in the expected range, the '@', and the XXfollowing character are simply printed to the stdout. Thus XXnormal use can be made of the '@' symbol in the document. XXA typical letter might look like: XXDate here XX@1 XX@2 XX@3 XX@4 XX@5 XXdear @6 XXIf lines one thru five of the list record contain the usual name, XXtitle, address, city-state-zip, aux 1 and the sixth line or aux 2 XXis the first name, then the program would substitute these values XXappropriately in their respective places. The merged document is XXsent (character by character) to the standard output. XXThus the merged documents can be sent anywhere the user desires XXby redirecting in the command line. A typical use would be: XX(cpm) mmerge listfile letterfile >lst: XX(unix) mmerge listfile letterfile | lpr XXIf six lines are not enough for some needs, one can always add XXmore descriptions to the structure 'record', and extend the XXswitch-case in mergit() appropriately. Also remember to include XXthe new structure elements in the forever loop in main(). XXHope you like it, if there are any questions, please drop me a XXnote via CIS or my business address: XXMatthew Rapaport XXSCAETRIX Co. XX222 Fifth St. XXPetaluma, CA 94952 XX(707) 778-7758 XXCIS [70371,255] @//E*O*F mmerge.doc// chmod u=rw,g=r,o=r mmerge.doc echo Inspecting for damage in transit... temp=/tmp/sharin$$; dtemp=/tmp/sharout$$ trap "rm -f $temp $dtemp; exit" 0 1 2 3 15 cat > $temp <<\!!! 15 26 143 letter 14 29 168 list 161 361 2885 mmerge.c 75 427 2574 mmerge.doc 265 843 5770 total !!! wc letter list mmerge.c mmerge.doc | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp if test -s $dtemp then echo "Ouch [diff of wc output]:" ; cat $dtemp else echo "No problems found." fi exit 0