本文介绍了转义bash变量中的特殊字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我尝试逐行读取包含文件路径的文件,并将文件SCP到另一台服务器,但由于文件名中的某些字符,如‘(’,‘)’,‘&;’等。我需要转义输入:
input.txt:
/folder1/folderA/filename+(oh+how+nice,+parantheses)
script.sh:
#!/bin/sh
promote_to=random.server.com
dev_catalog=/folderX/
uat_catalog=/folderY/
while read line
do
uat_path=$(echo "$uat_catalog$line" | sed -e "s/(/\(/g" | sed -e "s/)/\)/g")
dev_path=$(echo "$dev_catalog$line" | sed -e "s/(/\(/g" | sed -e "s/)/\)/g")
scp $dev_path user@$promote_to:$uat_path
scp $dev_path".atr" user@$promote_to:$uat_path".atr"
done < "input.txt"
输出:
-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory
-bash: /folder1/folderA/filename+(oh+how+nice,+parantheses): No such file or directory
usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]
[-l limit] [-o ssh_option] [-P port] [-S program]
[[user@]host1:]file1 [...] [[user@]host2:]file2
ssh: random.server.com: Name or service not known
lost connection
感谢任何形式的帮助。
推荐答案
这里的部分问题是本地和远程文件名的解析方式不同:本地文件名是直接使用的,所以您唯一需要做的就是用双引号将其括起来(就像@Ignacio的答案一样),但是远程文件名会被传递到远程外壳,该外壳通过另一层解析来运行它(引号和转义删除等)。因此,您只想将转义添加到远程路径。我还冒昧地稍微简化了sed
命令:
#!/bin/sh
promote_to=random.server.com
dev_catalog=/folderX/
uat_catalog=/folderY/
while read line
do
uat_path="$(echo "$uat_catalog$line" | sed -e 's/[()&]/\&/g')"
dev_path="$dev_catalog$line"
scp "$dev_path" "user@$promote_to:$uat_path"
scp "$dev_path.atr" "user@$promote_to:$uat_path.atr"
done < "input.txt"
请注意,我使用的sed
模式's/[()&]/\&/g'
只转义圆括号和与号;如果您的文件名包含任何其他外壳元字符,请确保将它们添加到[]
中的字符列表中。
这篇关于转义bash变量中的特殊字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!