如何在bash中连接使用printf格式化的字符串
我需要在循环中连接几个字符串,并将结果分配给变量: 格式化字符串示例:如何在bash中连接使用printf格式化的字符串,bash,shell,printf,Bash,Shell,Printf,我需要在循环中连接几个字符串,并将结果分配给变量: 格式化字符串示例: 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 +
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
您的代码看起来没问题。您确实需要做一件事,因为添加到
result
中时,它将包含空格,请引用它的扩展名:
result=$(printf '...' "$result" "$size" "$name" ...)
引用其他变量可能没有必要,但通常是个好主意
但是,未能引用
$result
不应导致它完全为空。您可能需要在while
循环中发布更多代码。如果要将$result和所有其他可能包含空格和其他特殊字符的变量用作程序或内置i的单个参数,请在其周围使用双引号n功能:
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手册页的参数部分)
在完整代码列表中,第二个“while read i”之前的“done”之后缺少管道符号
当你打电话的时候
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"
result=“”
对于/var/www/*;do中的名称
read size _u<我添加了变量$outbound的示例。printf中使用的其他变量与此类似。循环中没有其他变量。看起来问题不在printf中,而是在管道和循环中的某个地方。我添加了完整的源代码我更新了答案,主要问题可能是从最顶层的父pr访问结果环境变量ocessIs有没有POSIX安全的方法来替换Bash的+=
操作符?这是我的代码:ReplacementString=$(printf“%s”\\x%d“$ReplacementString”“CodePoint2”)
(我正在尝试解析UCD)输出:U”\x%dCodePoint2,
始终确保您在问题中发布的代码再现了您遇到的问题;您的原始帖子没有。原因result
为空是因为您在子shell中为其赋值;这些更改在子shell退出后消失。根据您的原始问题,我们无法知道这一点。另一方面--这是非常糟糕的代码。您永远不应该以这种方式解析ls
的输出;有关原因的解释,请参阅--另外,对每一行输入执行三次cat | grep
,效率极低。