I need to concatenate several strings in loop and assign result to variable:
Formatted string example:
result=$(printf '| %-15s| %-25s| %-15s| %-15s| %-15s\n' $size $name $visits $inbound $outbound);
From my view it should work like this:
result=''
while read somevar
do
...
outbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|awk '{ sum+=$11} END {print sum/1024/1024}'`
result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' $result $size $name $visits $inbound $outbound);
...
done
echo $result
But it doesn't :(
UPD:
Full code listing below:
www_path='/var/www';
result='';
cd /var/www/; ls -d */ | while read i ; do basename "$i" ; done
while read i;
do du -sh "$i"|
while read size name
do
visits=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk -F ' ' '{print $1}' | sort | uniq | wc -l|tr '\n' '\t'|sed 's/$/\t/'`
inbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk '{ sum+=$10} END {print sum/1024/1024}'|tr '\n' '\t'|sed 's/$/\t\t/'`
outbound=`cat "$www_path/$name/access.log"|grep \`date +"%d/%b/%Y"\`|grep -v "internal dummy connection"|awk '{ sum+=$11} END {print sum/1024/1024}'`;
result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")
done
done
echo $result
The += Operator in Bash Bash is a widely used shell in Linux, and it supports the '+=' operator to concatenate two variables. As the example above shows, in Bash, we can easily use the += operator to concatenate string variables.
You can concatenate two C-style strings in C++ using strcat() function.
String concatenation is the process of appending a string to the end of another string. This can be done with shell scripting using two methods: using the += operator, or simply writing strings one after the other.
Use double quotes around $result and all other variables that may contain blanks and other special characters if they are to be used as a single argument to a program or built-in function:
result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")
If you just want to assign the result of printf to a variable (as you did), you can also use
printf -v result '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound"
BTW: there also a += assignment operator that just appends to strings (see bash man page, section PARAMETERS).
In the full code listing, a pipe sign is missing after the 'done' before the second 'while read i'.
And when you call
echo $result
the contents of $result is already lost, since the printf is called in a sub process created by the pipe sign after 'do du ...'. The parent processes haven't access to the (environment) variables of the sub process.
I'd rather rewrite the code to something like
result=""
for name in /var/www/* ; do
read size __ < <(du -sh "$name")
name=${name##*/}
#insert the other stuff here and add arguments to printf
printf -v line '| %-15s| %-25s\n' "$size" "$name"
result+=$line
done
echo "$result"
The read < <(cmd)
expression is similar to cmd | read
but the former puts the command in the sub process instead, while the read is executed in the main process. This way, the variables set by read can be used in subsequent commands, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With