Экранирование обратной косой черты в путях Windows, переданных в программы Unix - PullRequest
6 голосов
/ 01 ноября 2011

Я пытаюсь избежать обратной косой черты в Cygwin, но это кажется почти невозможным Я много чего перепробовал, но ничего не получилось ..

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

Точнее, мне нужно получить команду для получения ввода в bash без потерять символы обратной косой черты. каждый раз, когда я пытаюсь передать аргумент, обратные слеши всегда исчезают, разрушая мой вклад. А я не знаю как я могу сказать, чтобы оставить только обратную косую черту на входе.

Я пробовал следующее, но ни один из них не работает

  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

Кстати, я хочу иметь возможность набирать C: \ Users \ Ted \ Music \ Enigma без цитаты. Один из этих псевдонимов работает при использовании кавычек.

Ted

Ответы [ 6 ]

10 голосов
/ 01 ноября 2011

Пожалуйста, прочитайте раздел с заголовком QUOTING в bash (1) (man bash).

В вашем первом примере,

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

оболочка интерпретирует (а затем удаляет) обратные слэши внутридвойные кавычки, поэтому первая команда echo видит только строку C:UsersTedDocumentsUnixScripts.

Во втором примере

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

одинарные кавычки правильно защищают обратную косую черту, как вы можете видетьзапустив только первую команду echo, без | xargs echo.

Во всех оставшихся примерах

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

, поскольку аргумент (C:\Users\Ted\Music\Enigma) без кавычек, один разснова оболочка интерпретирует и удаляет обратную косую черту до того, как команда (cyg0, cyg1, ...) когда-либо их увидит.И ...

Я хочу иметь возможность печатать C: \ Users \ Ted \ Music \ Enigma без кавычек.

Извините, это не может быть сделано,Если вы не ставите обратную косую черту в одинарных кавычках, оболочка интерпретирует каждую из них как символ кавычки для символа, следующего за ним, а затем удаляет обратную косую черту.

У вас есть несколько вариантов:

  1. Используйте одинарные кавычки в командной строке для защиты от обратной косой черты:

    cyg4 'C:\Users\Ted\Music\Enigma'
    
  2. Заключайте в кавычки каждый символ обратной косой черты отдельно, удваивая его, например,

    cyg4 C:\\Users\\Ted\\Music\\Enigma
    
  3. Вместо этого используйте косую черту:

    cyg4 C:/Users/Ted/Music/Enigma
    

Вариант 3 действительно может быть вашим лучшим решением.К сожалению, символ обратной косой черты - это очень особенный символ для всех оболочек Unix, и это вызывает много неприятностей при цитировании при работе с путями DOS / Windows.Но что не очень широко известно, так это то, что DOS / Windows также очень рады использовать косую черту (/) в качестве разделителя пути.Попробуйте.

Примечание. Из ваших нескольких функций cyg * верны только cyg1 и cyg4.Остальные используют некорректное цитирование.cyg1 полезен только с одним аргументом, поскольку он объединяет все аргументы в одну строку в кавычках, тогда как cyg4 может принимать и передавать несколько аргументов в cygpath.Однако, поскольку cyg4 передает только свои аргументы в кавычках, он не добавляет никакого значения;это действительно ничем не отличается от, например,

cygpath C:/Users/Ted/Music/Enigma

Удачи.

4 голосов
/ 13 октября 2012

Иногда полезно попробовать руководства по используемым программам :-). От 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.

Эта опция действительно сохраняет всю строку как есть. Попробуйте:

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

"-0" делает это за вас!

Обратите внимание, что для более чем одного аргумента вы должны завершать аргументы нулем, например, find ... -print0 или grep ... --null.

4 голосов
/ 23 ноября 2011

У меня была похожая проблема при чтении пути из проводника Windows, вставленного в командную строку:

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

Команда "read -r xyz" (с аргументом "-r") не интерпретирует одиночные обратные слеши в вставленном пути.

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

Витторио

2 голосов
/ 06 марта 2016

Я понимаю, что этот ответ довольно поздно для вечеринки ... но я наткнулся на этот вопрос, хотя сам столкнулся с той же проблемой.

Я использовал 'xargs' из установки Cygwin - И - я былвызывая его из обычной оболочки cmd.exe.

Для меня я просто использовал утилиту tr, которая также находится в папке Cygwin:

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

Это полностью решило мою «проблему слэша».

1 голос
/ 22 января 2015

Попробуйте:

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

xargs -0 объяснение опции (из gnu.org ):

"Имена входных файлов заканчиваются нулевым символом, а не пробелом, и любые кавычки и символы обратной косой черты не считаются специальными (каждый символ воспринимается буквально). Отключает конец строки файла, который рассматривается как любой другой аргумент. "

ИЛИ

Вы также можете достичь этого с помощью 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

Это заменит все одинарное \ на двойное \\, прежде чем оно будет передано в xargs, где двойное значение \\ будет затем возвращено к одиночному \ вместо исходного регистра от одного до нуля.

sed - это полезный инструмент потокового редактора, который можно использовать для простой замены текста. Вот учебник с некоторыми хорошими примерами.

Синтаксис подстановки следующий:

s/string_to_replace/replace_with/g

  • Модификатор g используется для замены всех вхождений. Без него будет заменен только первый матч.
  • Дополнительные обратные слеши в sed 's/\\/\\\\/g' используются для экранирования каждого \ специального значения символа. Итак, \\ будет буквальным символом \, а \\\\ будет \\.

Для без кавычек вы должны будете использовать \\ вместо \, как предполагает отмеченный ответ.

 echo C:\\Users\\Ted\\Documents\\Unix\\Scripts | xargs echo
1 голос
/ 01 марта 2014

У меня была такая же проблема, при преобразовании имен файлов, таких как c: \ dirname, в unix с использованием cygpath, я получал c: dirname и даже более странные вещи.

Оказывается, однако, что моей проблемой были имена файловЯ использовал входные данные пользователей, которые я извлекал командой read.Чтение, а не cygpath, вызывало мои проблемы, выбрасывая обратную косую черту.«read -r» исправил проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...