This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Counting Around Empty Lines in a file

Old posts that have not been replied to for several years.
Locked
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Counting Around Empty Lines in a file

Post by Darkj »

Basically, on rare occasions, sometimes my scripts add blank lines to a file, pretty sure I know how to fix that, but is there a way to count all the lines in the file, but tell it to ignore empty lines. Thanks.
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Re: Counting Around Empty Lines in a file

Post by user »

Read the file line by line and don't count the empty ones :P
D
Darkj
Halfop
Posts: 86
Joined: Sun Jul 06, 2003 9:58 pm

Post by Darkj »

But how do I ignore empty lines?
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

Darkj wrote:But how do I ignore empty lines?
By only counting the non-empty lines.
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Two ways to do it

Post by user »

\n+ in the regexp will count several linebreaks next to each other as one, and thus "ignore" the empty lines...

Code: Select all

proc countNonEmptyLines {file} {
	set d [read [set f [open $file]]]
	close $f
	expr {[regexp -all \n+ [string trim $d \n]]+1}
}
or if you, for some reason, don't want to keep the entire thing in memory:

Code: Select all

proc countNonEmptyLines {file} {
	set f [open $file]
	set i 0
	while {[gets $f l]>-1} {
		if {[string len $l]} {incr i}
	}
	close $f
	set i
}
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Instead of the last set i i think it should be return $i or something.. :)
Once the game is over, the king and the pawn go back in the same box.
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

caesar wrote:Instead of the last set i i think it should be return $i or something.. :)
No need for that. (return use more cpu than set)

Here's why this works (from http://tcl.tk/man/tcl8.4/TclCmd/proc.htm ):
When a procedure is invoked, the procedure's return value is the value specified in a return command. If the procedure doesn't execute an explicit return, then its return value is the value of the last command executed in the procedure's body.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

And what's the point of set i then?
Once the game is over, the king and the pawn go back in the same box.
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

caesar wrote:And what's the point of set i then?
Making the last returned value inside the proc be the contents of the variable. (set returns the value of the variable when called with one argument) If we were to remove the 'set' line, an empty string would be returned (the value returned by 'close')
Get it? :)
Last edited by user on Mon Sep 01, 2003 4:13 am, edited 1 time in total.
User avatar
strikelight
Owner
Posts: 708
Joined: Mon Oct 07, 2002 10:39 am
Contact:

Post by strikelight »

user wrote:return use more cpu than set
I'm just curious as to what you base this on?

EDIT:
Nevermind.. did some tests to verify:

Code: Select all

% set aa 1
1
% proc dd {} { global aa; return $aa }
% set bb [time dd]
66 microseconds per iteration
% proc dd {} { global aa; set aa }
% set bb [time dd]
45 microseconds per iteration
Interesting..
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

There's a page at the tcl wiki explaining this, but I can't find it right now...i'll post a link to it if I do.
User avatar
strikelight
Owner
Posts: 708
Joined: Mon Oct 07, 2002 10:39 am
Contact:

Post by strikelight »

user wrote:There's a page at the tcl wiki explaining this, but I can't find it right now...i'll post a link to it if I do.
Found the page:

http://mini.net/tcl/1044

However, it says :
set result can under certain conditions be equivalent to (or better than)' ..

It also goes on to say:
And in recent versions of Tcl there's no longer a performance penalty for using it (return) either. :^)

I tried on tcl8.4.1 (which seems pretty recent), but I guess I will have to try on 8.4.4 as well.

Edit: TCL 8.4.4 Results:

Code: Select all

% info patchlevel
8.4.4
% set aa 24
24
% proc dd {} {global aa; return $aa}
% time dd
36 microseconds per iteration
% proc dd {} {global aa; set aa}
% time dd
30 microseconds per iteration
While it is closer, the 'set' method still appears to be a tad faster. (atleast in this situation)
User avatar
user
 
Posts: 1452
Joined: Tue Mar 18, 2003 9:58 pm
Location: Norway

Post by user »

if you think about it...

Code: Select all

proc a {var} {set var}
only has one command invocation while

Code: Select all

proc b {var} {return $var}
has variable substitution AND a command invocation. So that pretty much explains where the extra cpu cycles go.

The command invocation is "compiled away" in the lastest version as you mentioned though, but apparently the two methods are still not equally demanding on the cpu. This must be because variable substitution is slower than command invocation in this particular case.
Locked