ZSH: Escape or quote a string with backslashes
Asked Answered
R

4

5

I wrote a little function, that "translates" a Windows path to a OSX path and opens it in the Finder. The function works perfectly with bash, but not with zsh (I use oh-my-zsh).

The problem is that it parses specific backslash combinations, for instance: \f, \a, \01, \02, \03, etc...

For example, this path string is the input:

"\60_Project\6038_Projekt_Part\05_development\assets\img\facebook"

After the translation function, the \f sequence (from img\facebook) is incorrectly translated as whitespace, producing the output:

"/60_Project/6038_Project_Part_developmentssets/img
                                                                                   acebook"

My goal is to just paste in a Windows path and not have to manually change anything.

How can I escape or quote a string with zsh, to get the result I want?

Here is the code I wrote:

function parsewinpath {
  echo $1 | sed -e 's/\\/\//g'
}

function openwinpath {
  echo "Opening..."
  open $(parsewinpath "/Volumes/myvolume$1")
}

Usage:

openwinpath '\60_Project\6038_Project_Part\05_development\assets\img\facebook'

The result should be that the Finder opens:

/Volumes/myvolume/60_Project/6038_Project_Part/05_development/assets/img/facebook
Raymund answered 7/9, 2017 at 14:18 Comment(0)
H
3

The problem is that echo is trying to interpret escape sequences in the string as it prints it. Some versions of echo do this; some do it only if you pass the -e option; some print "-e" as part of their output; some do ... other random things. Basically, if you give echo something that contains escapes and/or starts with "-", there's no telling what it'll do.

Option 1: Use printf instead. It's a little more complicated, because you have to give it a format string as well as the actual string to be printed, but it's much more predictable. Oh, and double-quote variable references:

function parsewinpath {
  printf '%s\n' "$1" | sed -e 's/\\/\//g'
}

Option 2: As @chepner pointed out, you can just skip echo, sed, and the whole mess, and use a parameter expansion to do the job:

function openwinpath {
  echo "Opening..."
  open "/Volumes/myvolume${1//\\//}"
}
Hypogeal answered 7/9, 2017 at 16:46 Comment(0)
L
4

You don't need parsewinpath at all. Just use parameter expansion to replace backslashes with forward slashes.

openwinpath /Volumes/myvolume${1//\\//}
Loaves answered 7/9, 2017 at 15:59 Comment(0)
H
3

The problem is that echo is trying to interpret escape sequences in the string as it prints it. Some versions of echo do this; some do it only if you pass the -e option; some print "-e" as part of their output; some do ... other random things. Basically, if you give echo something that contains escapes and/or starts with "-", there's no telling what it'll do.

Option 1: Use printf instead. It's a little more complicated, because you have to give it a format string as well as the actual string to be printed, but it's much more predictable. Oh, and double-quote variable references:

function parsewinpath {
  printf '%s\n' "$1" | sed -e 's/\\/\//g'
}

Option 2: As @chepner pointed out, you can just skip echo, sed, and the whole mess, and use a parameter expansion to do the job:

function openwinpath {
  echo "Opening..."
  open "/Volumes/myvolume${1//\\//}"
}
Hypogeal answered 7/9, 2017 at 16:46 Comment(0)
R
0

Just escape each backslash with another backslash:

openwinpath '\\60_Project\\6038_Project_Part\\05_development\\assets\\img\\facebook'

Ride answered 7/9, 2017 at 15:47 Comment(1)
Well, if I would do that, I could change the backslashes to forward slashes myself, but I want the script to do this annoying job! The goal is, to just paste in a path I got from colleagues, that are using Windows.Raymund
A
0

Sorry, I know I'm 5 years late, but I thought an explanation of the problem's root and a workaround might be worth it for anyone else who ends up here:

Bash has a certain syntax. It interprets backslashes in a certain way. So you can't paste text with backslashes into the Terminal.

However, if you've copied the text to the clipboard, you may be able to circumvent bash's syntax by using a shell command to read the clipboard inside your script. So instead of using $1 to get your path from your script's argument, use pbpaste to read the clipboard directly.

Asteria answered 14/12, 2022 at 0:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.