string bash中的字符串格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16028677/
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
string formatting in bash
提问by ShaunLangley
I have the following code that runs in a shell script
我有以下在 shell 脚本中运行的代码
foo=`seq 1 1 100`
for i in $foo; do
echo "input$i\_now"
done
Here's my question: Under some conditions, the output prints input1_now
whereas othertimes it prints input1\_now
. I'm sure something is different, but I can't figure out what makes it print one way or the other. If my code is
这是我的问题:在某些情况下,输出会打印,input1_now
而有时会打印input1\_now
. 我确定有些东西是不同的,但我无法弄清楚是什么让它以一种或另一种方式打印。如果我的代码是
for i in $foo; do
echo "input$i_now"
done
I will always get input
with the rest of the line being omitted.
我总是会input
忽略该行的其余部分。
I know I can use input${i}_now
instead and have it print correctly every time, but I'm mostly interested in understanding why the output is different under seemingly the same conditions.
我知道我可以input${i}_now
改用并每次都正确打印,但我最感兴趣的是理解为什么在看似相同的条件下输出不同。
UPDATE:
更新:
In the following example, the first part correctly formats the variables and text such that the \_
is replaced as _
. However, the last part required me to place variables in curly brackets in order to have them formatted correctly.
在以下示例中,第一部分正确设置了变量和文本的格式,以便将\_
替换为_
。但是,最后一部分要求我将变量放在大括号中,以便正确格式化它们。
echo "Enter Simulation #: "
read sim
g.mapset results
for i in `seq 1 1 100`; do
file=sim$sim\_run$i\_sum
g.copy $file\@expSim$sim\_$i,$file
file=sim$sim\_run$i\_average
g.copy $file\@expSim$sim\_$i,$file
for year in `seq 2004 1 2006`; do
file=sim$sim\_$year\_run$i\_sum
g.copy $file\@expSim$sim\_$i,$file
file=sim$sim\_$year\_run$i\_average
g.copy $file\@expSim$sim\_$i,$file
done
years="2004 2005 2006"
times=`seq -w 1 16 365`
runs=`seq 1 1 100`
for year in $years; do
for ptime in $times; do
for i in $runs; do
if [ $i -eq 1 ]; then
g.copy vect=sim${sim}_pts_${year}_${ptime}_run${i}@expSim${sim}_${i},sim${sim}_pts_${year}_${ptime}
fi
if [ $i -gt 1 ]; then
v.patch input=sim${sim}_pts_${year}_${ptime}_run${i}@expSim${sim}_${i} output=sim${sim}_pts_${year}_${ptime} -e -a --o
fi
done
done
done
回答by sastorsl
You need to explain to bash that you want the $i variable:
您需要向 bash 解释您想要 $i 变量:
foo=`seq 1 1 100`
for i in $foo; do
echo "input${i}_now"
done
The difference:
区别:
input$i_now # "input" + $i_now
input${i}_now # "input" + $i + "_now"
回答by rob mayoff
Is _
supposed to be a placeholder that is sometimes a different character?
被_
认为是一个占位符,有时是一个不同的角色?
In bash
, "input$i\_now"
with an actual _
will always produce input1\_now
. Inside double-quotes, bash
only removes a \
when it is followed by a $
, a `
, a "
, a \
, or a newline. See “Double Quotes” in the Bash Reference Manual. This is the POSIX standard behavior; see “Double-Quotes” in Shell Command Language.
在bash
,"input$i\_now"
用实际_
总会产生的input1\_now
。在双引号内,bash
仅\
当 a 后跟 a $
、 a `
、 a "
、 a\
或换行符时才删除 a 。请参阅Bash 参考手册中的“双引号”。这是 POSIX 标准行为;请参阅Shell 命令语言中的“双引号”。
UPDATE
更新
If you write "input$i_now"
, bash
will just print input
. It will not print input1
or input1_now
. It does this because _
is a valid parameter name character, so bash
thinks you are asking for the value of the i_now
parameter. Unless you have set i_now
to a non-empty string, bash
will expand $i_now
to the empty string, thus turning "input$i_now"
into input
.
如果你写"input$i_now"
,bash
只会打印input
。它不会打印input1
或input1_now
。它这样做是因为它_
是一个有效的参数名称字符,所以bash
认为您是在要求i_now
参数的值。除非你已经设置i_now
为非空字符串,bash
否则会扩展$i_now
为空字符串,从而"input$i_now"
变成input
.
UPDATE 2
更新 2
Now that you have posted real code, we can see what's going on.
现在您已经发布了真正的代码,我们可以看看发生了什么。
First of all, in the real code you posted, you never used double-quotes around a parameter expansion. This makes a difference.
首先,在您发布的实际代码中,您从未在参数扩展周围使用双引号。这有所作为。
Outside of double-quotes, a \
is always removed. See “Quote Removal” in the Bash Reference Manual. Hence input$i\_now
(with nosurrounding double-quotes) expands to input1_now
.
在双引号之外,a\
总是被删除。请参阅Bash 参考手册中的“引用删除”。因此input$i\_now
(没有周围的双引号)扩展为input1_now
.
However, as I explained in my first update, _
is a parameter name character. See “Name”?in Shell Command Language. So when bash
sees input$i_now
, it takes i_now
as the parameter name.
但是,正如我在第一次更新中所解释的,_
是参数名称字符。见“名称”?在shell命令行语言。所以当bash
看到时input$i_now
,它i_now
作为参数名称。
Whether or not you're using double-quotes, you mustseparate the parameter name from the following character, if bash
would otherwise treat the following character as part of the parameter name. You can do this by putting \
after the parameter name, or you can do it by putting the parameter name in {...}
.
无论您是否使用双引号,您都必须将参数名称与后面的字符分开,否则bash
会将后面的字符视为参数名称的一部分。您可以通过将\
参数名称放在后面来执行此操作,也可以通过将参数名称放在{...}
.
It is safer to always use {...}
, because (as you have discovered?) \
is handled differently depending on whether it's inside double-quotes. If you go back and add double-quotes later, and you have used \
, you will need to change the \
to {...}
anyway.
始终使用 更安全{...}
,因为(正如您所发现的?)\
根据它是否在双引号内而有不同的处理方式。如果您稍后返回并添加双引号,并且您使用了\
,则无论如何您都需要将 更改\
为{...}
。
UPDATE 3
更新 3
Here is a demonstration of the effects of \
, {...}
, and double-quoting. First, we set up some variables:
这里是的效果演示\
,{...}
以及双引号。首先,我们设置一些变量:
$ year=2004 ptime=1 i=1 sim=123
Here's what happens with no quoting whatsoever:
这是不引用任何内容时发生的情况:
$ echo vect=sim$sim_pts_$year_$ptime_run$i@expSim$sim_$i,sim$sim_pts_$year_$ptime
vect=sim1@expSim1,sim1
Here's what happens if we just use {...}
without double-quotes:
如果我们{...}
不使用双引号,会发生以下情况:
$ echo vect=sim${sim}_pts_${year}_${ptime}_run${i}@expSim${sim}_${i},sim${sim}_pts_${year}_${ptime}
vect=sim123_pts_2004_1_run1@expSim123_1,sim123_pts_2004_1
If we add double-quotes, they have no effect:
如果我们添加双引号,它们没有效果:
$ echo "vect=sim${sim}_pts_${year}_${ptime}_run${i}@expSim${sim}_${i},sim${sim}_pts_${year}_${ptime}"
vect=sim123_pts_2004_1_run1@expSim123_1,sim123_pts_2004_1
Here's what happens if we just use \
:
如果我们只使用,会发生以下情况\
:
$ echo vect=sim$sim\_pts\_$year\_$ptime\_run$i@expSim$sim\_$i,sim$sim\_pts\_$year\_$ptime
vect=sim123_pts_2004_1_run1@expSim123_1,sim123_pts_2004_1
Notice that each \
was removed. The shell removes a \
if it's not quoted.
请注意,每个都\
被删除了。\
如果没有引用,shell 将删除 a 。
If we add double-quotes, they prevent the shell from removing each \
:
如果我们添加双引号,它们会阻止 shell 删除每个\
:
$ echo "vect=sim$sim\_pts\_$year\_$ptime\_run$i@expSim$sim\_$i,sim$sim\_pts\_$year\_$ptime"
vect=sim123\_pts\_2004\_1\_run1@expSim123\_1,sim123\_pts\_2004\_1