posert@bonnie.ics.uci.edu (Bob Posert) (01/14/89)
I have a file with two words on each line, and want to process them in a shell script, but can't figure out how to get *the entire line* into a variable. I tried: foreach i (`cat file`) #misc processing end but i was set to each word, not line. Then I tried the same thing, but adding quotes at the beginning and end of every line in the input file. Basically the same thing happened, even though from the prompt, foreach i ("One Two") echo $i end echoed the words on the same line. Any ideas? Thanks in advance. --Bob -- Bob Posert I'm: posert@bonnie.ics.uci.edu or {sdcsvax|ucbvax}!ucivax!bonnie!posert
maart@cs.vu.nl (Maarten Litmaath) (01/14/89)
posert@bonnie.ics.uci.edu (Bob Posert) writes:
\I have a file with two words on each line, and want to
\process them in a shell script, but can't figure out
\how to get *the entire line* into a variable.
\I tried:
\ foreach i (`cat file`)
\ #misc processing
\ end
\but i was set to each word, not line.
foreach i ("`cat file`") # create 1 string
..."$i"... # avoid * and friends getting expanded
end
--
Lee Harvey Oswald was a patsy. |Maarten Litmaath @ VU Amsterdam:
Or a superman. |maart@cs.vu.nl, mcvax!botter!maart
marquez@pnet01.cts.com (Dan Castro) (01/16/89)
maart@cs.vu.nl (Maarten Litmaath) writes: >posert@bonnie.ics.uci.edu (Bob Posert) writes: >>I have a file with two words on each line, and want to >>process them in a shell script, but can't figure out >>how to get *the entire line* into a variable. >>I tried: >> foreach i (`cat file`) >> #misc processing >> end >>but i was set to each word, not line. > >foreach i ("`cat file`") # create 1 string > ..."$i"... # avoid * and friends getting expanded >end I had been trying to do the same sort of thing and came up with a different method. The script shown above didn't work on my system. (Microport V/AT 286 2.3) The following did work for both the Bourne and c shells... ---------------------cut here-------cut here-------------------- # expander # # expander processes the "datafile" a line at a time using the # "read" function. The resulting output is the original line # followed by the first two (white space separated) fields in # reverse order, on the same line. # expander() { while read line do one=`echo "$line" | awk ' { print $1 } '` two=`echo "$line" | awk ' { print $2 } '` echo "$line: $two $one" done } # main: shell execution starts here cat datafile | expander --------------------cut here---------cut here------------------- UUCP: {nosc ucsd hplabs!hp-sdd}!crash!pnet01!marquez ARPA: crash!pnet01!marquez@nosc.mil INET: marquez@pnet01.cts.com
geoff@warwick.UUCP (Geoff Rimmer) (01/17/89)
In article <4116@paris.ics.uci.edu> posert@bonnie.ics.uci.edu (Bob Posert) writes: > >I have a file with two words on each line, and want to >process them in a shell script, but can't figure out >how to get *the entire line* into a variable. > >I tried: > foreach i (`cat file`) > #misc processing > end >but i was set to each word, not line. > If you do foreach i ("`cat file`") #misc processing end you will get the whole line. However, when I tried this just now, I realised that if there are any wild cards (?,*,[,]) then it gives the strange error message end: No match when it gets to the line containing the ? or whatever. Can anyone explan this one? >Then I tried the same thing, but adding quotes at the beginning and >end of every line in the input file. Basically the same thing happened, >even though from the prompt, > foreach i ("One Two") > echo $i > end >echoed the words on the same line. I suppose when csh interprets the output of the `...` , it ignores the quotes, but I have no idea why it should do so!! Way back in my first year (and most of the second) I was there slaving away at sorting out which quotes to use in csh/sh and when or not to use a backslash etc, and I got so fed up, that I haven't written any scripts since (except for the simplest type) and now everything is in C. OK, it takes a lot longer to write, but it's a lot faster, it's more reliable, and a lot more powerful! > Bob Posert > I'm: posert@bonnie.ics.uci.edu or {sdcsvax|ucbvax}!ucivax!bonnie!posert Geoff ------------------------------------------------------------ Geoff Rimmer, Computer Science, Warwick University, England. geoff@uk.ac.warwick.emerald "It just goes to show, if you want something doing properly, it's best not to drink 16 pints of lager beforehand." - Filthy Rich and Catflap, 1986. ------------------------------------------------------------
posert@bonnie.ics.uci.edu (Bob Posert) (01/17/89)
Thanks to everyone who sent me the solution: foreach i ("`cat file`") #whatever end And special thanks go to Mike Khaw, who correctly pointed out that you lose leading whitespace and lines that are only whitespace by doing the above. Fortunately, it didn't matter for my application. --Bob -- Bob Posert I'm: posert@bonnie.ics.uci.edu or {sdcsvax|ucbvax}!ucivax!bonnie!posert
lukas@ihlpf.ATT.COM (00771g-Lukas) (01/18/89)
In article <4116@paris.ics.uci.edu> posert@bonnie.ics.uci.edu (Bob Posert) writes: > >I have a file with two words on each line, and want to >process them in a shell script, but can't figure out >how to get *the entire line* into a variable. Nobody mentioned IFS, so I thought Id through my $.02 in. The following will I think solve the problem: ifs_def=$IFS ifs_nl="\ " while read in; do echo "$in" # other stuff IFS="$ifs_nl" done <t.in IFS="$ifs_def" Now, Im not sure why the IFS change surrounds the redirection (my first impulse was to have it surround the "read"), however, it works correctly (empirically). It handles leading white space and special characters correctly. It has the additional benefit of working with sh, ksh, and csh. -- John Lukas att!ihlpf!lukas 312-510-6290
guy@auspex.UUCP (Guy Harris) (01/20/89)
>It has the additional benefit of working with sh, ksh, and csh.
"csh" has an IFS variable that you can set? News to me....
dberg@cod.NOSC.MIL (David I. Berg) (01/24/89)
In article <909@ubu.warwick.UUCP>, geoff@warwick.UUCP (Geoff Rimmer) writes: > In article <4116@paris.ics.uci.edu> posert@bonnie.ics.uci.edu (Bob Posert) writes: > > foreach i (`cat file`) > > #misc processing > > end > >but i was set to each word, not line. When I encountered the same problem I used an oscillating soft switch to keep track of which word to which I was was pointing. It's a kludge, but it works. > However, when I tried this just now, I realised that if there are any wild > cards (?,*,[,]) then it gives the strange error message "end: No match" Set the environment variable "nonomatch" to eliminate no matches. -- David I. Berg (dberg@nosc.mil) GENISYS Information Systems, Inc., 4250 Pacific Hwy #118, San Diego, CA 92110 MILNET: dberg@nosc.mil UUCP: {akgua decvax dcdwest ucbvax}!sdcsvax!noscvax!dberg
lukas@ihlpf.ATT.COM (00771g-Lukas) (01/24/89)
In article <872@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >>It has the additional benefit of working with sh, ksh, and csh. > >"csh" has an IFS variable that you can set? News to me.... In the words of the great philosopher, Mr. Peevee, "Well, now, I dont know about that." Im not a csh user, so I dont know. I just wrote the script as given, and tried it with sh, ksh, and csh, and it worked for all three. -- John Lukas att!ihlpf!lukas 312-510-6290
guy@auspex.UUCP (Guy Harris) (01/26/89)
>I just wrote the script as given, and tried it with sh, ksh, and csh, and it >worked for all three. The "csh" on your system must be something other than the C shell, then, because the C shell is quite different from the Bourne shell, and it complained as soon as it saw ifs_def=$IFS because it said that IFS was an undefined variable; when I defined it, it gave ifs_def=: Command not found. instead. The way you set shell variables is different in the C shell, so it didn't like "ifs_def=$IFS". Most non-trivial Bourne shell scripts probably don't work at all if you run them under the C shell. (Obligatory clarification, to ward off "Wrong! See, here's *my* trick for doing that" postings: Most non-trivial Bourne shell scripts probably don't work at all under the C shell unless you do a Larry Wall-style "ooops, wrong shell, I'll feed myself to 'sh'" trick, or have some other trick, perhaps along the lines of those programs that represented valid C, Pascal, and FORTRAN source through clever use of the three languages' comment conventions.)
lukas@ihlpf.ATT.COM (00771g-Lukas) (01/26/89)
In article <891@auspex.UUCP> guy@auspex.UUCP (Guy Harris) writes: >>I just wrote the script as given, and tried it with sh, ksh, and csh, and it >>worked for all three. > >The "csh" on your system must be something other than the C shell, then, >because the C shell is quite different from the Bourne shell, and it >complained as soon as it saw > > ifs_def=$IFS No, it turns out that my "csh" is in fact the C shell, but I must have been doing something wrong. Im hoping that you can enlighten me. I made the script executable, then issued it from csh, vis: lpf lukas> csh % foo # correct! results of foo here % exit lpf lukas> However, when I issued: lpf lukas> csh foo It failed with messages like you suggested. So, I threw in a "ps" into "foo", and found that "csh" forked a "sh" process to actually run "foo", and that is why it worked. I guess I didnt expect that. Why was a "sh" child produced, instead of another "csh" (or, anyway, a "ksh", which is my login shell, and the value of SHELL)? Any ideas? Parenthetically, I did the same sort of thing with "ksh" instead of "csh", and another "ksh" (NOT a "sh") was forked to run the "ps". As a side issue, is there any way to know, from within a process, what the "current" shell is? It would seem to me that an environment variable would be best. Something like "CURR_SHELL", that would have "sh", "ksh", etc., or somesuch. I suggested some such to David Korn for the ksh, but he did not see the need. I suppose that I could use the output of "ps", then track back child to parent until I got to a shell, but that seems like an awful lot of work. Any ideas on this? -- John Lukas att!ihlpf!lukas 312-510-6290
gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/27/89)
In article <7449@ihlpf.ATT.COM> lukas@ihlpf.UUCP (00771g-Lukas,J.) writes: >It failed with messages like you suggested. So, I threw in a >"ps" into "foo", and found that "csh" forked a "sh" process to actually >run "foo", and that is why it worked. I guess I didnt expect that. >Why was a "sh" child produced, instead of another "csh" (or, anyway, >a "ksh", which is my login shell, and the value of SHELL)? Any ideas? >Parenthetically, I did the same sort of thing with "ksh" instead of "csh", >and another "ksh" (NOT a "sh") was forked to run the "ps". The implementors of your csh should be congratulated for getting this right (for a change). csh is supposed to feed scripts to a Bourne shell. The only exception would be if your kernel doesn't support #! execs but (ALL) your shells are expected to take care of this, in which case the #! line should be interpreted and the appropriate processor run to handle the script. The Korn shell is supposedly upward-compatible with the Bourne shell, so it is able to handle scripts directly instead of invoking a separate shell.
guy@auspex.UUCP (Guy Harris) (01/27/89)
>Why was a "sh" child produced, instead of another "csh" (or, anyway, >a "ksh", which is my login shell, and the value of SHELL)? Any ideas? A long time ago, in a galaxy far, far away (well, I dunno, how far is Berkeley, CA from Napierville, IL?), Bill Joy wrote a shell for either V6 or V7 UNIX. At least when run under V7, it wasn't compatible with the existing UNIX shell; since people wanted to use the C shell as their login shell, and possibly write C shell scripts, but still be able to run Bourne shell scripts as well, both the Bourne and C shells were hacked up to try to recognize each other's scripts and run the other shell if they recognized a "foreign" script. The versions of the Bourne and C shells that I'm familar with that do this check the first character of the script; the C shell assumes that a script beginning with ":" is a Bourne shell script, and the Bourne shell assumes that a script beginning with "#" is a C-shell script. (":" was a no-op command used as a sort of comment in the Bourne shell; the C shell accepted comments beginning with "#" which were *real* comments not scanned by its parser, so ":" tended not to be used in C shell scripts, and since the Bourne shell did not originally have "#" comments, "#" tended not to be used in Bourne shell scripts.) (Subsequently, Berkeley added the "#!" mechanism - suggested, I'm told, by Dennis Ritchie - that allows "exec" system calls to "directly" execute shell scripts; the kernel recognizes "#!" as the first two characters of a file it's told to execute, and sucks a pathname from the first line of the file and runs the program with that pathname, handing it the pathname of the file it was originally told to execute as an argument. This obviates the need for the Bourne/C shell hacks, and just in time - more recent Bourne shells support "#" comments, so you can't validly use "#" as the first character as the deciding factor any more.) >Parenthetically, I did the same sort of thing with "ksh" instead of "csh", >and another "ksh" (NOT a "sh") was forked to run the "ps". Yup, "ksh" basically thinks of itself as the only shell in the world (as did the original Bourne shell), and if it tries to "exec" a program and fails because it's not an executable image, it kicks off another "ksh" to run it. ("#!" allows you to mark shells as Bourne, C, or Korn shell scripts - or as "awk" scripts, or....)
sar@datcon.UUCP (Simon A Reap) (01/27/89)
In article <7372@ihlpf.ATT.COM> lukas@ihlpf.UUCP (00771g-Lukas,J.) writes: >.............. I just wrote >the script as given, and tried it with sh, ksh, and csh, and it >worked for all three. Ah, but don't all of these shells (and others) run scripts via the Bourne shell (except for the dodgy and almost-undocumented fudge of having the first line start with a '#' or '#!/bin/csh etc etc to force use of the C shell. How many of us *haven't* been caught by this, prettifying a working shell script by adding header comments, then finding it no longer works as the Bourne shell constructs get munged by the wonderful Cshell :-( ) -- Enjoy, yerluvinunclesimon Opinions are mine - my cat has her own ideas Reach me at sar@datcon.co.uk, or ...!mcvax!ukc!pyrltd!datcon!sar
greywolf@unisoft.UUCP (The Grey Wolf) (01/28/89)
In article <9511@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >In article <7449@ihlpf.ATT.COM> lukas@ihlpf.UUCP (00771g-Lukas,J.) writes: >> [ when he typed "csh foo", foo was run with sh instead ] > >The implementors of your csh should be congratulated for getting this >right (for a change). csh is supposed to feed scripts to a Bourne shell. Where are you getting your documentation, Doug? Since when, if you type % csh foo does it feed "foo" to the Bourne shell? This is not correct, and certainly not normal! If I feed a script to csh, csh had better run it, since that was my intention. Otherwise, it would be rather redundant, what? >The only exception would be if your kernel doesn't support #! execs but >(ALL) your shells are expected to take care of this, in which case the >#! line should be interpreted and the appropriate processor run to handle >the script. System V, release 3 does not support #! execs. I know, because I *work* with them all bloody day. #! is constantly ignored. --- Roan Anderson, Software Engineer, UniSoft Corp. 6121 Hollis St. Emeryville, CA 94608 My opinions are my own and not those of UniSoft Corporation. If I want your opinion, I'll give it to you. -- ...TheysaidDoyouseethebiggreenglowinthedarkhouseuponthehill?andIsaidYesIseethebiggreenglowinthedarkhouseuponthehillTheresabigdarkforestbetweenmeandthebiggreenglowinthedarkhouseuponthehillandalittleoldladyonaHoovervacuumcleanersayingIllgetyoumyprettyandyourlittledogTototoo I don't even *HAVE* a dog Toto...
gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/28/89)
In article <1837@unisoft.UUCP> greywolf@unisoft.UUCP (The Grey Wolf) writes: >In article <9511@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: >>In article <7449@ihlpf.ATT.COM> lukas@ihlpf.UUCP (00771g-Lukas,J.) writes: >>> [ when he typed "csh foo", foo was run with sh instead ] No, that wasn't what he said! He was running interactively under csh, and typing "foo" invoked an "sh" to interpret it. >System V, release 3 does not support #! execs. I never said it did.