LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware
User Name
Password
Slackware This Forum is for the discussion of Slackware Linux.

Notices


Reply
  Search this Thread
Old 08-15-2011, 10:15 PM   #1
onyxbird
Member
 
Registered: Aug 2004
Location: The Silicon Forrest
Distribution: slackware
Posts: 39

Rep: Reputation: 15
String concat in for loop


Hello,

Have a little trouble with string concatenation in for loop in bash....

okay so here is my code
<code>
var1="one"
var2="two"
var3="three"
var4="four"

numbers="$var1 $var2
$var3 $var4"
echo "$numbers"
</code>

gives me the output I want

output: one two
three four

but in a for loop

<code>
var1="one"
var2="two"
var3="three"
var4="four"
numbers="$var1 $var2
$var3 $var4"

for num in $numbers
do
echo "$num"
done
</code>

I don't get my expected output

output: one
two
three
four

thanks for any help!
 
Old 08-15-2011, 10:21 PM   #2
T3slider
Senior Member
 
Registered: Jul 2007
Distribution: Slackware64-14.1
Posts: 2,367

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
You need to quote $numbers in your for loop declaration. Right now it is separating parameters by whitespace and the quotes within the loop are meaningless (since there are no terms with spaces in them).
Code:
for num in "$numbers"
do
echo "$num"
done
 
Old 08-15-2011, 10:34 PM   #3
onyxbird
Member
 
Registered: Aug 2004
Location: The Silicon Forrest
Distribution: slackware
Posts: 39

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by T3slider View Post
You need to quote $numbers in your for loop declaration. Right now it is separating parameters by whitespace and the quotes within the loop are meaningless (since there are no terms with spaces in them).
Code:
for num in "$numbers"
do
echo "$num"
done
Thanks so much that worked great!
 
Old 08-15-2011, 11:02 PM   #4
T3slider
Senior Member
 
Registered: Jul 2007
Distribution: Slackware64-14.1
Posts: 2,367

Rep: Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843Reputation: 843
Heh, looking at this again that loop isn't doing anything...it's treating the whole expression as one term. A better construct would be the following:
Code:
while read num; do
echo "$num"
done < <(echo "$numbers")
which separates by line and gives the correct number of terms (2). Note that this is a bashism...you could use
Code:
echo "$numbers" | while read num; do
echo "$num"
done
to be more portable but this spawns a subshell which produces fun results when creating/modifying variables within the loop.

Unless I've misunderstood your intent, of course.
 
Old 08-16-2011, 02:19 AM   #5
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
First, please use [code][/code] tags around your code, to preserve formatting and to improve readability.


Next, it's vitally important to understand the way bash handles arguments, whitespace, and word-splitting. Don't do anything else until you've finished reading this page: http://mywiki.wooledge.org/Arguments


Now that that's out of the way, a for loop works on lists of words (as defined by the shell's word-splitting operation). Each element is taken into the variable in turn, and the subsequent operations performed. So if you don't quote the input variable, then it will split it into individual words wherever there's whitespace (by default at least). But if you do quote it, it will treat the whole thing as a single block. Neither option does exactly what you want.

Therefore, when you want to operate on lines, you should use a while+read loop instead (as demonstrated by T3slider). The read command grabs whole lines of input (by default), so you don't have to worry about shell word-splitting occurring on other whitespace.

I would, however, use a here string to take input from a variable, rather than process substitution, as it doesn't require running a subshell.

Code:
while read num; do
     echo "$num"
done <<<"$numbers"
Finally, a variable is designed to hold an individual string of characters. When you have multiple strings to work on (strings of strings), you should generally use an array instead. Set each array element to hold one line, and you can go back to using a for loop, and call on the array's index numbers to manipulate the individual elements.

Code:
numbers=( one two three four )

for i in 0 2 ; do
	echo "${numbers[i]} ${numbers[i+1]}"
done
When you have the time, read through this guide in its entirety. It will teach you pretty much all the background concepts you need to know for good bash scripting: http://mywiki.wooledge.org/BashGuide
 
  


Reply



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
perl concat a string to array casperdaghost Programming 7 05-09-2011 10:08 PM
[SOLVED] String concat problem in shell script snowball0916 Programming 10 11-21-2010 04:02 AM
Concat string will NULL in mysql tanveer Linux - Server 6 06-25-2008 02:16 PM
Concat string (not ended ...) os2 Programming 2 03-25-2005 03:23 PM
loop through string with perl lfur Programming 2 07-03-2004 08:05 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Distributions > Slackware

All times are GMT -5. The time now is 02:43 AM.

Main Menu
Advertisement
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
Open Source Consulting | Domain Registration