如何将文件名空格替换为\ ,使Bash脚本读取TSV路径执行rsync拷贝
需求背景
现有shell脚本从多空格分隔的文件读取路径信息:第一列为源文件路径,第二列为目标路径,脚本调用rsync执行拷贝操作。
现有问题
路径中存在含空格的文件名,需将文件名内部的空格替换为\ 适配shell读取规则。使用命令sed -r 's/^\s+//;s/\s+/\\ /g' test2.tsv处理时,会将源、目标路径之间的分隔空格也添加反斜杠,导致脚本无法识别两个路径字段。
示例原始路径对:
/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg /mapped-data/data20/data3/header-background copy.jpg
原sed命令错误输出:
/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background\ copy.jpg\ /mapped-data/data20/data3/header-background\ copy.jpg
期望输出(仅替换文件名内部空格,保留路径分隔的多空格不变):
/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background\ copy.jpg /mapped-data/data20/data3/header-background\ copy.jpg
实现方案
推荐awk实现(逻辑更稳定)
指定字段分隔符为连续2个及以上空白,分别处理两个路径字段内的空格,不会影响分隔符:
awk -F'[[:space:]]{2,}' '{ gsub(/ /, "\\ ", $1); gsub(/ /, "\\ ", $2); print $1 " " $2; }' test2.tsv
命令说明
-F'[[:space:]]{2,}'指定字段分隔符为连续2个及以上的空白,正确拆分源、目标两个路径字段gsub(/ /, "\\ ", $1)替换源路径内所有单个空格为\gsub(/ /, "\\ ", $2)替换目标路径内所有单个空格为\print $1 " " $2输出处理后的路径,中间用3个空格分隔,对齐原有格式
如需直接修改原文件,可执行:
awk -F'[[:space:]]{2,}' '{gsub(/ /, "\\ ", $1);gsub(/ /, "\\ ", $2);print $1 " " $2}' test2.tsv > tmp && mv tmp test2.tsv
sed实现方案
通过正则匹配仅替换左右无空格的单个空格(路径内部空格),不处理连续的分隔空格:
sed -r 's/^\s+//;s/([^ ]) ([^ ])/\1\\ \2/g' test2.tsv
内容的提问来源于stack exchange,提问作者mht.haque
相关产品推荐
相关产品推荐

