shell script to...
Tom Christiansen
tchrist at convex.COM
Fri Apr 12 03:10:43 AEST 1991
>From the keyboard of neil at ms.uky.edu (Neil Greene):
:Any sed gurus that would like to explain how to accomplish the following. I
:have not masterd the art of sed or awk.
:
:I have a file that contains drug names and next to the drug name is the drug
:group.
:
:> Dipyrone Analgesic
:> Nefopam Analgesic
:> Thiosalicylic Acid Analgesic
:> Xylazine Analgesic
:> Chloramphenicol Antibiotic
:
:A need a shell script that will read from another (ascii) data file, find an
:occurance of a DRUG_NAME, write the line to another (ascii) file and append
:the appropriate DRUG_TYPE to the new line.
:
:# line with drug name in it
:xxxx 01/02/90 xxxxxx xxxxx xxx x xxxxxxx Dipyrone .... xxxx xxxxx
:
:# rewrite new line to new ascci file
:xxxx 01/02/90 xxxxxx xxxxx xxx x xxxxxxx Dipyrone .... xxxx xxxxx Analgesic
Here's a simple-minded perl script to do this. It reads from
"drugs.types" to load the table, then reads stdin and writes stdout
according to your spec:
open (TYPES, "drugs.types") || die "can't open drugs.types: $!";
while (<TYPES>) {
split;
$types{$_[0]} = $_[1];
}
while (<>) {
chop;
print;
study; # compile pattern space for speed
foreach $name (keys %types) {
if (/\b$name\b/) {
print ' ', $types{$name};
last;
}
}
print "\n";
}
No checking is done on the input validity in the TYPES file. This would
also be a bit slow if you had a big table because of all the re_comp()s that
get called. A faster, albeit less obvious way to do this would be to use
an eval. This makes it look like a bunch of constant strings, which when
combined with the "study" statement, does B-M one better, and really
blazes. Another possible speed optimization would be to make the if's
into a cascading if/elsif block, which would get internalized into one big
switch statement, and perl would jump directly to the right case.
open (TYPES, "drugs.types") || die "can't open drugs.types: $!";
while (<TYPES>) {
split;
$types{$_[0]} = $_[1];
}
$code = <<EO_CODE;
while (<>) {
chop;
print;
EO_CODE
for $name (keys %types) {
$code .= <<EO_CODE;
if (/\\b$name\\b/) {
print ' ', \$types{"$name"}, "\n";
next;
}
EO_CODE
}
$code .= <<EO_CODE;
print "\n";
}
EO_CODE
print $code;
eval $code;
die $@ if $@;
--tom
More information about the Comp.unix.questions
mailing list