Escaping backslashes in window paths passed to unix programs

I am trying to avoid the backslash in cygwin, but it seems almost impossible I tried a lot of things, but nobody works correctly.

echo "C:\Users\Ted\Documents\Unix\Scripts" | xargs echo echo 'C:\Users\Ted\Documents\Unix\Scripts' | xargs echo 

In particular, I need to get a command to enter bash without losing backslash characters. every time I try to pass an argument, the backslash always disappears, ruining my contribution. And I don’t know how I can say to just leave a backslash at the input.

I tried the following but nothing works

  alias cyg0='cygpath '$*' ' alias cyg1='cygpath "$*" ' alias cyg2='cygpath "'$*'"' alias cyg3='cygpath ' $@ ' ' alias cyg4='cygpath " $@ " ' alias cyg5='cygpath "' $@ '"' Ted@Machine01 ~ $ cyg0 C:\Users\Ted\Music\Enigma C:UsersTedMusicEnigma Ted@Machine01 ~ $ cyg1 C:\Users\Ted\Music\Enigma cygpath: can't convert empty path Ted@Machine01 ~ $ cyg2 C:\Users\Ted\Music\Enigma cygpath: can't convert empty path Ted@Machine01 ~ $ cyg3 C:\Users\Ted\Music\Enigma C:UsersTedMusicEnigma Ted@Machine01 ~ $ cyg4 C:\Users\Ted\Music\Enigma C:UsersTedMusicEnigma Ted@Machine01 ~ $ cyg5 C:\Users\Ted\Music\Enigma cygpath: can't convert empty path 

By the way, I want to be able to type C: \ Users \ Ted \ Music \ Enigma without the quotation mark. One of these aliases works when using quotes.

Ted

+4
source share
6 answers

Please read the QUOTING section in bash (1) ( man bash ).

In the first example

 echo "C:\Users\Ted\Documents\Unix\Scripts" | xargs echo 

the shell interprets (and then removes) the backslash in double quotes, so the first echo command only sees the line C:UsersTedDocumentsUnixScripts .

In your second example

 echo 'C:\Users\Ted\Documents\Unix\Scripts' | xargs echo 

single quotes correctly protect backslashes, as you can see by running only the first echo command without | xargs echo | xargs echo .

In all other examples

 cyg0 C:\Users\Ted\Music\Enigma cyg1 C:\Users\Ted\Music\Enigma ... 

since the argument ( C:\Users\Ted\Music\Enigma ) is incorrect, the shell is interpreted again and removes the backslash before the command ( cyg0 , cyg1 , ...) ever sees them. AND...

I want to be able to type C: \ Users \ Ted \ Music \ Enigma without quotes.

Sorry, this is not possible. If you do not put the backslash in single quotes, the shell will interpret each of them as a quotation mark for the subsequent character, and then remove the backslash.

You have several options:

  • Use single quotes on the command line to protect backslashes:

     cyg4 'C:\Users\Ted\Music\Enigma' 
  • Specify each backslash character separately, doubling it, for example.

     cyg4 C:\\Users\\Ted\\Music\\Enigma 
  • Use slashes instead:

     cyg4 C:/Users/Ted/Music/Enigma 

Option 3 may indeed be your best bet. Unfortunately, the backslash character is a very special character for all Unix shells, and this causes a lot of link problems when using DOS / Windows paths. But it is not known that DOS / Windows also enjoys using a slash ( / ) as a path separator. Give it a try.

Note. Of your few cyg * functions, only cyg1 and cyg4 are correct. Others use incorrect quoting. cyg1 is useful with only one argument, since it combines all the arguments together on one line, and cyg4 can accept and pass multiple arguments to cygpath. However, since cyg4 only passes its quoted arguments, it does not add any value; it really is no different from, for example,

 cygpath C:/Users/Ted/Music/Enigma 

Good luck.

+7
source

I had a similar problem while reading the path from the explorer window inserted in the command line:

 echo "Please enter path (copy n paste from Win-Explorer):" read -r myWinPath; 

The read -r xyz command (with the -r argument) does not interpret single backslashes in the inserted path.

 myNewCygwinPath=`cygpath -a $myWinPath`; echo $myNewCygwinPath; 

Vittorio

+3
source

It is sometimes useful to give guidance on the programs used :-). From man xargs :

 OPTIONS -0, --null Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (ev- ery character is taken literally). Disables the end of file string, which is treated like any other argument. Useful when input items might contain white space, quote marks, or back- slashes. The GNU find -print0 option produces input suitable for this mode. 

This option really saves the entire line as is. Try:

 echo 'C:\Users\Ted\Documents\Unix\Scripts' | xargs -0 echo 

"-0" does it for you!

Note that for more than one arg argument, the arguments must be null, for example, find ... -print0 or grep ... --null .

+2
source

I admit that this answer is rather late for the party ... but I came across this question, experiencing the same problems.

I used "xargs" from the Cygwin installation - AND - I called it from the regular cmd.exe shell.

For me, I just used the tr utility, which is also located in the Cygwin folder:

dir /b /s /a *.txt | tr "\\" "/" | xargs ...

This completely solved my "slash problem".

+2
source

I had the same problem when converting file names, such as c: \ dirname, to unix using cygpath. I was getting c: dirname and even weirder things.

It turns out, however, that my problem was that the names of the files I used were entered by users, which I extracted using the read command. Reading, not cygpath, caused my problems by throwing backslashes. "read -r" fixed the problem.

+1
source

Try:

 echo "C:\Users\Ted\Documents\Unix\Scripts" | xargs -0 echo echo 'C:\Users\Ted\Documents\Unix\Scripts' | xargs -0 echo 

xargs -0 option (from gnu.org ):

"Input file names end with a null character, not a space, and any quotation marks and backslash characters are not considered special (each character is taken literally). Disables the end of the line of the file, which is treated like any other argument."

OR

You can also achieve this with sed :

 echo "C:\Users\Ted\Documents\Unix\Scripts" | sed 's/\\/\\\\/g' | xargs echo echo 'C:\Users\Ted\Documents\Unix\Scripts' | sed 's/\\/\\\\/g' | xargs echo 

This will replace all single \ to double \\ before it is transferred to xargs, where double \\ will then be deleted to a single \ instead of the original case of a single single.

sed is a useful stream editing tool that you can use to easily replace text. Here is a tutorial with good examples.

The syntax for substitution is as follows:

s/string_to_replace/replace_with/g

  • The g modifier is used to replace all occurrences. Without it, only the first match will be replaced.
  • An additional backslash in sed 's/\\/\\\\/g' used to exclude each \ character. So, \\ will be the literal character \ , and \\\\ will be \\ .

For without quotes, you should use \\ instead of \ , as the marked answer suggests.

  echo C:\\Users\\Ted\\Documents\\Unix\\Scripts | xargs echo 
+1
source

Source: https://habr.com/ru/post/1379072/


All Articles