我需要在循环中连接几个字符串并将结果赋给变量:
格式化字符串示例:
result=$(printf '| %-15s| %-25s| %-15s| %-15s| %-15s\n' $size $name $visits $inbound $outbound);
从我看来它应该是这样的:
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
但事实并非如此:(
UPD:
以下完整代码:
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
答案 0 :(得分:10)
在$ result和所有其他可能包含空格和其他特殊字符的变量周围使用双引号,如果要将它们用作程序或内置函数的单个参数:
result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")
如果您只想将printf的结果分配给变量(就像您所做的那样),您也可以使用
printf -v result '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound"
顺便说一句:还有一个+ =赋值运算符,它只是附加到字符串上(参见bash手册页,PARAMETERS部分)。
在完整的代码清单中,在第二个“读取i”之前的“完成”之后缺少管道标志。
当你打电话
echo $result
$ result的内容已经丢失,因为printf是在'do du ...'之后由管道符号创建的子进程中调用的。父进程无法访问子进程的(环境)变量。
我宁愿将代码重写为类似
的代码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"
read < <(cmd)
表达式类似于cmd | read
,但前者将命令放在子进程中,而read则在主进程中执行。这样,read设置的变量也可以用在后续命令中。
答案 1 :(得分:2)
您的代码看起来不错。你需要做的一件事,因为result
将在你添加空格时包含空格,引用它的扩展:
result=$(printf '...' "$result" "$size" "$name" ...)
引用其他变量可能没有必要,但通常是个好主意。
不能引用$result
不应该导致它完全空白。您可能需要在while
循环中发布更多代码。