nikost
nikost

Reputation: 858

Using bash script to replace underscore with a backslash and underscore

I have a bash script that I want to add a backslash in front of all underscores. The script searches for all files in a directory and saves the file name to a variable file. Then in the variable I want to replace every instance of _ with \_.

I have looked at several questions on sed about search and replace as well as how to treat special characters, but none of them seemed to apply correctly to this scenario.

#!/bin/bash
file=some_file_name.f90 # I want this to read as some\_file\_name.f90
# I have tried the following (and some more i didnt keep track of)
fileWithEscapedUnderscores=$(sed 's/_/\\_/g' <<<$file)
fileWithEscapedUnderscores=$(sed 's/_/\_/g' <<<$file)
fileWithEscapedUnderscores=$(sed 's/_/\\\_/g' <<<$file)
fileWithEscapedUnderscores=${file/_/\_/}

It seems like I need to escape the backslash. However, if I do that I can get the backslash but no underscore. I also tried simply inserting a backslash before the underscore, but that also had issues.

Upvotes: 0

Views: 1088

Answers (1)

tripleee
tripleee

Reputation: 189387

The simple and obvious solution is to escape or quote the backslash in the parameter expansion.

You also had the slashes wrong; your attempt would merely replace the first one, with the literal string \_/.

To recap, the syntax is ${variable/pattern/replacement} to replace the first occurrence of pattern, and ${variable//pattern/replacement} to replace all occurrences.

fileWithEscapedUnderscores=${file//_/\\_}
# or
fileWithEscapedUnderscores=${file//_/'\_'}

Your first sed attempt should have worked, too; but avoid calling an external process when you can use shell builtins.

Separately, probably take care to use quotes around variables with file names, though it would not matter in your example; see also When to wrap quotes around a shell variable

Upvotes: 1

Related Questions