Replace slash in Bash
Asked Answered
Q

5

70

Let's suppose I have this variable:

DATE="04\Jun\2014:15:54:26"

Therein I need to replace \ with \/ in order to get the string:

"04\/Jun\/2014:15:54:26"

I tried tr as follows:

echo "04\Jun\2014:15:54:26" | tr  '\' '\\/'

But this results in: "04\Jun\2014:15:54:26".

It does not satisfy me. Can anyone help?

Quillan answered 6/6, 2014 at 8:45 Comment(4)
man tr would tell you why it doesn't work. You could use sed.Poll
Why not create DATE in that format ? Also if you are echoing and writing the date before tr/sed/ect why not write it in that format ?Sempach
What is it that you are trying to do here? Replace forward slashes with backslashes or escaping all forward slashes? This question could use some clearing up. :)Tipi
Why do you need to escape the forward slashes in the first place?Hecate
H
121

No need to use an echo + a pipe + sed.

A simple substitution variable is enough and faster:

echo ${DATE//\//\\/}

#> 04\/Jun\/2014:15:54:26
Haihaida answered 6/6, 2014 at 9:3 Comment(2)
This doesn't seem to work in Bash 4.2.25 -- it only replaces the first slash. For example: FileDirRelativeToProjectRoot="source\scripts\components\screens\picker_view"; echo "${FileDirRelativeToProjectRoot/\\//}" prints source/scripts\components\screens\picker_viewOribella
Just figured it out, and this approach does work. You need to make sure you use two forward slashes after the variable name. So, in my example, ${FileDirRelativeToProjectRoot//\\//}. Otherwise, it just replaces the first one. Somewhat subtle...Oribella
A
16

Use sed for substitutions:

sed 's#/#\\/#g' < filename.txt > newfilename.txt

You usually use "/" instead of the "#", but as long as it is there, it doesn't matter.

I am writing this on a windows PC so I hope it is right, you may have to escape the slashes with another slash.

sed explained, the -e lets you edit the file in place. You can use -i to create a backup automatically.

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html
Argonaut answered 6/6, 2014 at 8:50 Comment(0)
H
9

here you go:

kent$  echo "04/Jun/2014:15:54:26"|sed 's#/#\\/#g'  
04\/Jun\/2014:15:54:26

your tr line was not correct, you may mis-understand what tr does, tr 'abc' 'xyz' will change a->x, b->y, c->z,not changing whole abc->xyz..

Hardnett answered 6/6, 2014 at 8:50 Comment(0)
G
9

You can also escape the slashes, with a slightly less readable solution than with hashes:

echo "04/Jun/2014:15:54:26" | sed 's/\//\\\//g'
Glamorous answered 19/10, 2018 at 8:27 Comment(0)
D
7

This has not been said in other answers so I thought I'd add some clarifications:

tr uses two sets of characters for replacement, and the characters from the first set are replaced with those from the second set in a one-to-one correspondance. The manpage states that

SET2 is extended to length of SET1 by repeating its last character as necessary. Excess characters of SET2 are ignored.

Example:

echo abca | tr ab de    # produces decd
echo abca | tr a de     # produces dbcd, 'e' is ignored
echo abca | tr ab d     # produces ddcd, 'd' is interpreted as a replacement for 'b' too

When using sed for substitutions, you can use another character than '/' for the delimiter, which will make your expression clearer (I like to use ':', @n34_panda proposed '#' in their answer). Don't forget to use the /g modifier to replace all occurences: sed 's:/:\\/:g' with quotes or sed s:/:\\\\/:g without (backslashes have to be escaped twice).

Finally your shortest solution will probably be @Luc-Olivier's answer, involving substitution, in the following form (don't forget to escape forward slashes too when part of the expected pattern):

echo ${variable/expected/replacement}     # will replace one occurrence
echo ${variable//expected/replacement}    # will replace all occurrences
Dizen answered 19/10, 2018 at 10:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.