bash 如何在bash中连接用printf格式化的字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15992897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to concatenate strings formatted with printf in bash
提问by user947668
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+=} 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 }' | 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+=} 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+=} END {print sum/1024/1024}'`;
result=$(printf '%s| %-15s| %-25s| %-15s| %-15s| %-15s\n' "$result" "$size" "$name" "$visits" "$inbound" "$outbound")
done
done
echo $result
回答by Jacob
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 和所有其他可能包含空格和其他特殊字符的变量用作程序或内置函数的单个参数,请在 $result 和所有其他变量周围使用双引号:
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 的结果分配给一个变量(就像您所做的那样),您也可以使用
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).
顺便说一句:还有一个 += 赋值运算符,它只是附加到字符串(参见 bash 手册页,参数部分)。
In the full code listing, a pipe sign is missing after the 'done' before the second 'while read i'.
在完整的代码清单中,在第二个 'while read i' 之前的 'done' 之后缺少管道符号。
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.
$result 的内容已经丢失,因为 printf 在“do du ...”之后由管道符号创建的子进程中调用。父进程无法访问子进程的(环境)变量。
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.
的read < <(cmd)
表达式类似于cmd | read
在子过程代替,但前者放命令,而读在主处理中执行。这样, read 设置的变量也可以在后续命令中使用。
回答by chepner
Your code looks OK. One thing you do need to do, since result
will contain whitespace as you add to it, is quote its expansion:
你的代码看起来不错。您需要做的一件事result
是引用它的扩展,因为添加到它时将包含空格:
result=$(printf '...' "$result" "$size" "$name" ...)
Quoting the other variables may not be necessary, but it is usually a good idea.
引用其他变量可能没有必要,但这通常是一个好主意。
Failing to quote $result
shouldn't cause it to be completely blank, however. You might need to post more of the code in your while
loop.
$result
然而,不引用不应该导致它完全空白。您可能需要在while
循环中发布更多代码。