Экранирование обратной косой черты в путях Windows, передаваемых программам unix

#bash #cygwin

#bash #cygwin

Вопрос:

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

   echo "C:UsersTedDocumentsUnixScripts" | xargs echo
  echo 'C:UsersTedDocumentsUnixScripts' | 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:UsersTedMusicEnigma
  C:UsersTedMusicEnigma

  Ted@Machine01 ~
  $ cyg1 C:UsersTedMusicEnigma
  cygpath: can't convert empty path

  Ted@Machine01 ~
  $ cyg2 C:UsersTedMusicEnigma
  cygpath: can't convert empty path

  Ted@Machine01 ~
  $ cyg3 C:UsersTedMusicEnigma
  C:UsersTedMusicEnigma

  Ted@Machine01 ~
  $ cyg4 C:UsersTedMusicEnigma
  C:UsersTedMusicEnigma

  Ted@Machine01 ~
  $ cyg5 C:UsersTedMusicEnigma
  cygpath: can't convert empty path
 

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

Ted

Комментарии:

1. У меня была такая же проблема. Я хотел запустить «dir / b / s * .txt», чтобы получить набор имен файлов, а затем передать их в xargs для обработки, но вывод обратной косой черты команды Windows dir не очень хорошо сочетался с xargs. В конце я использовал «найти . вместо этого -name *.txt», в котором используются косые черты. (Я использую xargs и find из пакета cygwin, но в командной оболочке Windows.)

2. Установите x параметр, чтобы точно видеть, как bash обрабатывает ваши строки. Просто проблема set -x .

Ответ №1:

Пожалуйста, прочтите раздел, озаглавленный ЦИТИРОВАНИЕ в bash(1) ( man bash ) .

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

 echo "C:UsersTedDocumentsUnixScripts" | xargs echo
 

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

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

 echo 'C:UsersTedDocumentsUnixScripts' | xargs echo
 

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

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

 cyg0 C:UsersTedMusicEnigma
cyg1 C:UsersTedMusicEnigma
...
 

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

Я хочу иметь возможность вводить C:UsersTedMusicEnigma без кавычек.

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

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

  1. Используйте одинарные кавычки в командной строке, чтобы защитить обратную косую черту:
     cyg4 'C:UsersTedMusicEnigma'
     
  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
 

Удачи.

Комментарии:

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

Ответ №2:

Иногда полезно попробовать руководства по используемым программам 🙂 . Из 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:UsersTedDocumentsUnixScripts' | xargs -0 echo
 

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

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

Комментарии:

1. Ваши обратные косые черты будут удалены до того, как строка попадет в xargs.

2. @bobbogo Ваше замечание было правильным для первоначального ответа, но я думаю, что это был просто недосмотр. Идея использования -0 очень полезна (и я забыл, что опция сохраняет все специальные символы), поэтому я взял на себя смелость исправить ошибку, на которую вы указали, чтобы сделать ответ более полезным в качестве схемы.

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

Ответ №3:

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

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

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

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

Vittorio

Ответ №4:

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

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

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

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

Это полностью решило мою «проблему с косой чертой».

Ответ №5:

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

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

Ответ №6:

Попробуйте:

 echo "C:UsersTedDocumentsUnixScripts" | xargs -0 echo
echo 'C:UsersTedDocumentsUnixScripts' | xargs -0 echo
 

объяснение параметра xargs -0 (из gnu.org ):

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

или

Вы также можете добиться этого с помощью sed:

 echo "C:UsersTedDocumentsUnixScripts" | sed 's/\/\\/g' | xargs echo
echo 'C:UsersTedDocumentsUnixScripts' | sed 's/\/\\/g' | xargs echo
 

Это заменит все single на double \ , прежде чем оно будет передано в xargs, где double \ затем будет заменен на single , вместо исходного значения single на none .

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

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

s/string_to_replace/replace_with/g

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

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

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