LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 11-06-2011, 02:04 AM   #46
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackware64 13.37-multilib
Posts: 537

Rep: Reputation: 74

altered the script here like this:
Code:
#!/bin/bash

bylet()
{
	val=0
	iter=1000000
	for((i=0;i<iter;i++))
	do
		let val+=i	
	done

	echo ${val}
}

other()
{
	val=0
	iter=1000000
	for((i=0;i<iter;i++))
	do
		((val+=i))
	done
	echo ${val}
}
time bylet
time other
To reduce on the dereferences still got me the rather big difference of:
499999500000

real 0m10.552s
user 0m10.253s
sys 0m0.236s
499999500000

real 0m8.684s
user 0m8.413s
sys 0m0.234s

That's nearly 2 seconds; While the dereferencing saved 2 seconds; The difference got halved;
Changing the for loop to the old style reduced the time equally in both:

499999500000

real 0m7.705s
user 0m7.433s
sys 0m0.176s
499999500000

real 0m5.640s
user 0m5.542s
sys 0m0.089s

The difference stays 2 seconds in an iteration of 1 million simple calculations;
(( ))-style calculations are also built-in shell and in my belief generally a much stronger method.

Things get really weird when you add a little stuff:
Code:
#!/bin/bash

bylet()
{
	val=0
	iter=1000000
	for i in {0..999999}
	do
		let val+=i
		if [[ $val > 10000000 ]]
		then
			let val=5
		fi
	done

	echo ${val}
}

other()
{
	val=0
	iter=1000000
	for i in {0..999999}
	do
		((val+=i))
		if ((val > 10000000 )) 
		then 
			((val=5)) 
		fi
	done
	echo ${val}
}
time bylet
time other
 
Click here to see the post LQ members have rated as the most helpful post in this thread.
Old 01-09-2012, 06:47 AM   #47
MadeInGermany
LQ Newbie
 
Registered: Dec 2011
Posts: 4

Rep: Reputation: Disabled
Quote:
Originally Posted by Darren[UoW] View Post
I am using the following code to read line by line from a file, however my problem is that $value=0 at the end of the loop possibly because bash has created a subshell for the loop or something similar. How can I solve this.


value=0;

while read line
do
value=`expr $value + 1`;
echo $value;
done < "myfile"

echo $value;


Note: This example just counts the number of lines, I actually desire to do more complex processing than this though, so 'wc' is not an alternative, nor is perl im afraid.


Thanks Darren.
Indeed a while loop is a block, that can be executed in a sub shell.
A sub shell is a fork of the main shell, so it inherits the variables, but there is no easy way to copy its variables back to the main shell.
It depends on the implementation:
Traditional Unix shells make it a sub shell when the block's input/output is redirected or piped.
Your work-around then is:

Code:
value=0
#save &0 in the unused &5
exec 5<&0
# read &0 from file
exec <"myfile"
while read line
do
value=...
...
done
#restore &0
exec <&5
echo $value
Posix shells, ksh, bash, zsh only make a sub shell when the block's input/output is piped (and they support the built-in $((numeric expression)).Darren's code works.

Ksh and zsh handle the last part of a pipe in the main shell, so even this one works:

Code:
value=0
cat "myfile" | while read line
do
value=...
...
done
echo $value
 
Old 05-31-2012, 06:02 PM   #48
keirvt
Member
 
Registered: Sep 2006
Location: Sydney Australia
Distribution: fedora/Ubuntu
Posts: 80

Rep: Reputation: 15
Problem easy solved by using kshesll

#!/bin/ksh
# Using kshell so that the variable value is seen outside while loop
value=0;

while read line
do
value=`expr $value + 1`;
echo $value;
done < "myfile"

echo $value;
 
Old 05-31-2012, 11:13 PM   #49
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackware64 13.37-multilib
Posts: 537

Rep: Reputation: 74
A few notes on that last post: I think the fipo was written by engraving letters in stone and somehow they've been able to digitize this.

Next thing: use code tags, like shown below.
Backticks are soooo 2011... use $() instead

That'd make your script look like this (changed a few more things - but essentially the same)
Code:
#!/bin/ksh
#Using Korn Shell to ease scoping of variables
value=0;

while read line
do
  ((value ++))
  printf "\r%05d" ${value}
done < "myfile"

printf "\nValue of \$value after the loop: %d\n" ${value}
 
Old 12-12-2012, 12:11 AM   #50
Red_Lv
LQ Newbie
 
Registered: Dec 2012
Posts: 1

Rep: Reputation: Disabled
the script works well in my pc

e...
are you sure that the script you posted show 0 at the end..
for i copy the code in my pc and it works as expected.
 
Old 07-04-2013, 04:08 AM   #51
hfreyer
LQ Newbie
 
Registered: Apr 2013
Posts: 4

Rep: Reputation: Disabled
If you need to get whitespace at the beginning or end of the lines
you can locally modify IFS. Here is a small "wc" clone example:
Code:
cat baz
bar
  foo  
     foo bar
# Only leading blanks are used.
Code:
a=0; b=0; c=0; 
while IFS="" read -r line; do 
  a=$((a+1))            # line count
  set -- $(echo $line)
  b=$((b+${#@}))        # word count
  c=$((c+${#line}+1))   # char count
done < baz
echo "$a $b $c"
wc baz
output is:
Code:
3 4 23
 3  4 23 baz

Last edited by hfreyer; 07-04-2013 at 04:21 AM.
 
Old 07-04-2013, 08:16 PM   #52
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,243
Blog Entries: 15

Rep: Reputation: 233Reputation: 233Reputation: 233
Quote:
Originally Posted by Darren[UoW] View Post
I am using the following code to read line by line from a file, however my problem is that $value=0 at the end of the loop possibly because bash has created a subshell for the loop or something similar. How can I solve this.
value=0;

while read line
do
value=`expr $value + 1`;
echo $value;
done < "myfile"

echo $value;
Quote:
I actually desire to do more complex processing than this though, so 'wc' is not an alternative, nor is perl im afraid.
And I expect that you don't need other scripting languages like Ruby as well? If so I think you just have to use Bash, as I see that you're probably using a different shell unless your file "myfile" is actually empty?. I've handled many shells already including the original bourne shell and I don't recall a shell that spawns a subprocess on a while loop unless that loop is reading a pipe but perhaps the very old ones does. Anyway if you have bash you could do it like this and it should be best enough:
Code:
#!/bin/bash

value=0

while read -r line; do  ## -r to prevent backslashes to escape characters.
    (( value += 1 ))
    echo "$value"  ## take note of the importance of placing string inside doublequotes especially when in a normal bash statement
done < "myfile"

echo "$value"
 
  


Reply

Tags
content, do, file, from, how, name, possibilities, read, script, write


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
BASH: read every line in the files and use the line as parameters as another program tam3c36 Programming 10 12-07-2010 01:42 PM
bash: read a line from file zokik Linux - General 6 12-10-2008 09:24 AM
shell script that read each line separatly xpucto Programming 6 09-20-2005 08:06 AM
Shell Script to read 500files from the command line saravanan1979 Programming 1 09-22-2004 09:44 AM
linux scripting help needed read from file line by line exc commands each line read atokad Programming 4 12-26-2003 10:24 PM


All times are GMT -5. The time now is 01:35 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration