String Bash:Can';t将字符串附加到现有字符串-它似乎会覆盖该字符串的开头
这是一个帮助我们创建dhcpd.conf文件的脚本 示例输入(例如mac选项卡-;-选项卡IP) 预期产出String Bash:Can';t将字符串附加到现有字符串-它似乎会覆盖该字符串的开头,string,bash,line-endings,String,Bash,Line Endings,这是一个帮助我们创建dhcpd.conf文件的脚本 示例输入(例如mac选项卡-;-选项卡IP) 预期产出 Host 27-48 { hardware ethernet DC:D3:21:75:61:90 ; fixed-address 10.25.131.17 ; } #host 27-48 { hardware ethernet ; fixed-address ; } 当前输出的行如下所示: Host 27-48 { hardware ethernet 00:16:6B:C8:3D:C9
Host 27-48 { hardware ethernet DC:D3:21:75:61:90 ; fixed-address 10.25.131.17 ; }
#host 27-48 { hardware ethernet ; fixed-address ; }
当前输出的行如下所示:
Host 27-48 { hardware ethernet 00:16:6B:C8:3D:C9 ; fixed-address 10.25.129.185
代码中的特定行我被卡住了
outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second"
如果我尝试添加;}
outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second ; }"
我明白了:
; } 27-48 { hardware ethernet 00:16:6B:C8:3D:C9 ; fixed-address 10.25.129.185
问题是,每当我将“;}”附加到上述行的末尾时,它都会覆盖该行的开头。我尝试了一些技巧来解决这个问题,例如将上面的行写入字符串,然后尝试附加到字符串,但同样的问题也发生了。我有一个想法,将整个内容导出到一个文件中,然后将文件重新加载到一个数组中,这样我就可以追加,但这似乎有点过分了
for ((j=1; j<=${sizes[i]}; j++ )); do
#split line, read split as two entries for an arrIN
IN=(${line[counter+1]})
arrIN=(${IN//;/ })
first="${arrIN[0]}"
second=${arrIN[1]}
if [ ${lineSize[counter+1]} -gt 5 ]
then
#sed 's/$/ ; }/' $outputLine > newoutputLine
outputLine="Host $((names[i]))-$((startingNumber+counter)) { hardware ethernet $first ; fixed-address $second"
echo $outputLine
else
echo "#host $((names[i])) $((startingNumber+counter)) { hardware ethernet ; fixed-address ; }"
fi
counter=$((counter+1))
done
((j=1;j newoutputLine)的
outputLine=“主机$((名称[i])-$((起始编号+计数器)){硬件以太网$第一;固定地址$第二”
echo$输出线
其他的
echo“#主机$((名称[i]))$((启动号+计数器)){硬件以太网;固定地址;}”
fi
计数器=$((计数器+1))
完成
正如在对该问题的评论中所解释的那样,问题是变量$second
值末尾的一个CR(0xD
,\r
)字符,该字符可以通过以下方式删除:second=“${second/$'\r'/}”
本答案的其余部分解释了症状并提供了背景信息
问题是,每当我将“;}”附加到上述行的末尾时,它都会覆盖该行的开头 “覆盖行首”几乎总是指向嵌入的(
0xD
,\r
)字符,当字符串打印到终端时,该字符显示为覆盖行首:
$ printf 'abc\rd' # `printf '\r'` produces a CR
dbc # It LOOKS LIKE 'd' replaced 'a', but that's an artifact of printing to the terminal.
仅因为终端将CR(\r
)解释为“将光标放在行的开头”,所以d
-在\r
之后的剩余字符串-显示为“覆盖”字符串已打印部分的开头
您可以使用cat-et
可视化嵌入的CRs(和其他控制字符),将它们表示为^M
:
$ printf 'abc\rd' | cat -et
abc^Md # ^M represents a CR (\r)
如您所见,d
实际上并没有覆盖字符串开头的a
CR(
\r
)实例在Unix文本处理领域中很少使用。如果它们确实作为文本数据的一部分出现,则通常来自使用CRLF(\r\n
)行结尾的Windows源,而不是仅使用Unix LF(\n
)行结尾。
通常,最简单的方法是在将数据与Unix实用程序一起使用之前删除CR(\r
)实例
有许多现有答案涵盖了这一领域,通常建议使用第三方实用程序,可通过许多平台的软件包管理器轻松安装(例如,Ubunutu上的sudo apt install dos2unix
,或macOS上的brew install dos2unix
,via)
或者
- 对于已经存储在变量中的文本,使用基于参数扩展的方法;例如,
second=“${second/$'\r'/}”
- 对于文件,可以充当临时的
dos2unix
$second
——可能在${arrIN[1]}的结尾有一些有趣的东西
清楚地说明您的输入变量,并提供准确的预期输出。您的bash
代码是创建dhcpd.conf
文件,还是只想在末尾使用;}
对该文件进行适当编辑?更新的示例输入。bash代码不是创建dhcpd.conf,而是创建最终将被合并的一部分使用子网部分(即复制和粘贴)。已经提供了一个输出,将更新另一个“空格”的输出。必须有回车符潜入(即,您的输入必须有Windows行结尾)。请尝试运行,例如,second=“${second/$'\r'/}”
将其剪下。输入是excel中的列,粘贴到记事本或记事本++中。我会试试看,谢谢。可能就是这样。编辑:就是这样!非常感谢!如果您将此作为答案添加,我将对其进行投票。我认为这是一个“特殊字符”问题。
$ printf 'abc\rd' | cat -et
abc^Md # ^M represents a CR (\r)