to simplify: lets say I have a column of number in ascii format. I would like
to subtract one from every number except on the last line.
The actual problem is more difficult but basically I need to test if I am
on the last line and NOT do something.
* is there a variable called LINES_IN_FILE which I could compare NR
(which is the current line) to?
* this may be related to the FILENAME variable.
* I guess I could set a variable to the wc (wordcount) of the file
in the BEGIN{} section, but that is not too efficient.
* instead of printing a line I could set it to a variable and once
I read in the next line I could then print the variable (which would
be the previous line). The END{} segment would then print the last
line. This is sort of a pain-shift-the-login-in-the-file solution.
Does anybody have a good idea, or can tell me what is the best alternative?
I just recently started awk-ing ...
Thank you,
Holger.
What? No eof() function in awk?? Seems to work in my a2p'd version. :-)
--tom
--
Tom Christiansen tch...@convex.com convex!tchrist
"AT&T -- anything better is illegal."
-- Keith Lofstrom, comp.unix.bsd, "AT&T sues BSDI" thread
Not to my knowledge.
> * this may be related to the FILENAME variable.
In what way?
> * I guess I could set a variable to the wc (wordcount) of the file
> in the BEGIN{} section, but that is not too efficient.
Forget putting it in the BEGIN section -- in order to do it that way, with
most awk's I know, you end up having to allow shell-substitution, which means
you have to escape all of your awk code (for {, }, $n, etc.), and it just
becomes a mess. Instead, pass in the variable on the command line. It's
a lot cleaner. E.g. (to follow your simplification):
set -- `wc -l < /tmp/input_file`
awk '{
if (NR == lines_of_input)
print $1
else
print $1 - 1
}' lines_of_input=$1 /tmp/input_file
> * instead of printing a line I could set it to a variable and once
> I read in the next line I could then print the variable (which would
> be the previous line). The END{} segment would then print the last
> line. This is sort of a pain-shift-the-login-in-the-file solution.
Yup. Unless you're REALLY hurting for file I/O bandwidth, I'd go with the
"wc" solution. The total amount of CPU used is not likely to be much different
between the two approaches, and the "staggered" version lands you with messy,
incomprehensible, high-bug-potential awk code.
If you really ARE hurting for file I/O, then perhaps you could consider
preprocessing your input by sed to stick in a sentinel value before the last
line, and triggering on that:
cat /tmp/input_file | sed '${
i\
!SENTINEL!
}' | awk '{
if ($0 ~ /^!SENTINEL!$/) {
at_end = 1
next
}
if (at_end)
print $1
else
print $1 - 1
}'
The downside, of course, besides a little kludginess, is having two processes
running concurrently, with a pipeline between them...
------------------------------------------------------------------------------
ke...@cfctech.cfc.com | Kevin Darcy, Unix Systems Administrator
...destroyer!cfctech!kevin | Technical Services (CFC)
Voice: (313) 759-7140 | Chrysler Corporation
Fax: (313) 758-8173 | 25999 Lawrence Ave, Center Line, MI 48015
------------------------------------------------------------------------------
as in:
$ awk '
> (NR>1) {print last}
> {last=$0}' <<EOF
> aaaa
> bbbb
> cccc
> EOF
aaaa
bbbb
$
Mandeep.
----------------------------------------------------------------------
Those who do not understand Unix are condemned to reinvent it, poorly.
-- Henry Spencer
----------------------------------------------------------------------