Home > Mobile >  How to replace a space with backslash and space "\ " so bash shell script can read the fi
How to replace a space with backslash and space "\ " so bash shell script can read the fi

Time:11-02

I have a script which takes source and destination information from a tsv file separated by space. The first column indicates source file path, and second column is destination. My rsync command reads source and destination information and performs copy operation.

But the issue is source and destination files both contain filename with white space (header-background copy.jpg) and as we know that when bash shell reads a file name (with space), it replace the space with backslash followed by space “\ ”

/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

My question is how I can replace the space with “\ ” so shell can read it. I tried with using below sed command

sed -r 's/^\s //;s/\s /\\ /g' test2.tsv

but there is a problem as above sed command also adds a backslash after the source path. As I have mentioned that my script takes source and destination information from the .tsv file so having a slash added is a problem here. Below is the output of the sed command.

/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

what I want is something like covert from

/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

to

/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

CodePudding user response:

tsv file separated by space

At least use a tab, because a tab is less likely to appear in a path than a space.

Remark: Did you know that only the / and the NULL char are forbidden in filenames in Linux filesystems? That means that everything but the NULL char can appear in a path...

Let's say that your file is now tab delimited and your paths don't include newlines nor tabs. Here's how you can read it in BASH:

while IFS=$'\t' read filepath1 filepath2
do
    declare -p filepath1 filepath2
done <<< "/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg"$'\t'"/mapped-data/data20/data3/header-background copy.jpg"

Output:

declare -- filepath1="/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg"
declare -- filepath2="/mapped-data/data20/data3/header-background copy.jpg"

If you need to explicitly escape a variable then you can use printf '%q'

filepath1="/data-prod/bigdata/abc/test/1143-1003-004_1143-1003-905/static/common/images/header-background copy.jpg"
filepath2="/mapped-data/data20/data3/header-background copy.jpg"

rsync -av "$filepath1" user@server:"$(printf '%q' "$filepath2")"

CodePudding user response:

Using sed, one way would be to group the match and return it with a back reference appending the back slash

sed 's/\([A-Za-z0-9\/][^\.]*\) /\1\\ /g' input_file
/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
  • Related