如何使用 sed 用空格替换文件路径?

如何使用 sed 用空格替换文件路径?

我有许多不同的文件,其中包含一个字符串。我需要用路径替换此字符串,尽管路径包含空格。到目前为止,我有以下内容:

for a in files_[a-z][a-z]_all\.conf ; do

fileWithPath="~/Downloads/files_config_linux/auth-user-pass files_userpass.txt"
otherOne="auth-user-pass mullvad_userpass.txt"

sed -i 's|'$otherOne'|'$fileWithPath'|g' $a

done

但我明白

sed:-e 表达式 #1,字符 16:未终止的“s”命令

我的问题是如何用带有空格的路径正确地替换该字符串。

谢谢

答案1

你的表情

's|'$otherOne'|'$fileWithPath'|g'

产生不带引号的字符串

s|auth-user-pass mullvad_userpass.txt|~/Downloads/files_config_linux/auth-user-pass files_userpass.txt|g

然后根据空格字符将其解析为几个单词。第一个单词是

s|auth-user-pass

然后传递给sed正确抱怨缺少第二个|分隔符。

要将整个s命令sed作为单个参数传递,您需要将其括起来。最简单的方法是将整个表达式括在双引号中:

"s|$otherOne|$fileWithPath|g"

shell 在双引号内执行变量替换,因此这将产生带引号的字符串

"s|auth-user-pass mullvad_userpass.txt|~/Downloads/files_config_linux/auth-user-pass files_userpass.txt|g"

sed然后将其作为单个参数按预期传递。

将文件名参数括在双引号中也是很好的做法$a,这样可以防止文件名中出现空格,但对于您来说这并不是绝对必要的,因为您的模式files_[a-z][a-z]_all\.conf不会匹配任何包含空格的文件名。

答案2

你的壳会裂开未引用字符串(在您的情况下由参数/变量扩展产生)到值周围的单词IFS...参见单词拆分...那是一回事。

您的 shell 可能会将带有修改过的引号的命令行参数传递给被调用的程序……这是另一回事。

他们说亲眼看见一次胜过听到一百次。做一次胜过看一百次。...

如果您在 Bash shell 中启用命令跟踪set -x,然后sed按照以下方式发出命令:

$ set -x
$
$ fileWithPath="~/Downloads/files_config_linux/auth-user-pass files_userpass.txt"
$ otherOne="auth-user-pass mullvad_userpass.txt"
$
$ sed -i 's|'$otherOne'|'$fileWithPath'|g'
+ sed -i 's|auth-user-pass' 'mullvad_userpass.txt|~/Downloads/files_config_linux/auth-user-pass' 'files_userpass.txt|g'
sed: -e expression #1, char 16: unterminated `s' command

...您可以看到您的命令行实际上是如何构建并传递给程序的sed,并且正如您所看到的,您提供的脚本被分解为多个部分(添加了引号)...并且就程序而言,sed只有第一组匹配的引号被视为脚本's|auth-user-pass',并且由于没有提供,因此以下引号甚至不被视为或添加到脚本中-e(以指示嵌套命令,尽管-e需要语法正确的命令才能工作),因此,事实上,该s命令并没有在该上下文中终止......因此出现以下消息:

sed:-e 表达式 #1,字符 16:未终止的“s”命令

现在,您可以看到幕后情况,将上述内容与以下内容进行比较:

$ sed -i 's|'"$otherOne"'|'"$fileWithPath"'|g'
+ sed -i 's|auth-user-pass mullvad_userpass.txt|~/Downloads/files_config_linux/auth-user-pass files_userpass.txt|g'
sed: no input files

或者:

$ sed -i "s|$otherOne|$fileWithPath|g"
+ sed -i 's|auth-user-pass mullvad_userpass.txt|~/Downloads/files_config_linux/auth-user-pass files_userpass.txt|g'
sed: no input files

...这应该足以通过“观察”和“行动”来弄清楚到底发生了什么。

相关内容