2009-08-20 2 views
1

Update:Как я могу canonicalize пути файлов Windows в Perl?

я могу сделать это более простая проблема:

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

Я хочу, чтобы превратить это:

vlc.plugin.path = C:\Program Files\JekyllV0.9.2\\VLC_1.0.0\\plugins 

в:

vlc.plugin.path = C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins 

Оригинальный вопрос:

Я хочу изменить следующее в файл с помощью Perl Regex:

  • всех вхождений одных задних косых черт на два назад слэши
  • всех вхождений одной косых черт, чтобы два назад слэша

Я попробовал следующее:

perl" -p -i.orig -e "s#\\#\\\\#g" -e "s#/#\\\\#g" %VIDEOLOG_PROPERTIES_FILE% 

, где% VIDEOLOG_PROPERTIES_FILE% содержит:

vlc.plugin.path = C:\Program Files\JekyllV0.9.2/VLC_1.0.0/plugins 
+2

... и что случилось? – chaos

+0

Не знаете, как MSWindows справляется с этими вещами, но вы можете еще раз попытаться ускользнуть от всех ваших обратных косых черт s # \\\\ # \\\\\\\\ # g – Inshallah

+0

"... и что случилось? - хаос" , да, это то, что делает Perl. (просто шучу, мне нравится Perl ;-)) – p4bl0

ответ

6

Для основной замены:

perl -p -i.orig -e "s#[/\\]#\\\\#g" %VIDEOLOG_PROPERTIES_FILE% 

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

perl -p -i.orig -e "s#(?<!/)/(?!/)#\\\\#g; s#(?<\\)\\(?!\\)#\\\\#g" %VIDEOLOG_PROPERTIES_FILE% 
+0

Можете ли вы объяснить, почему это будет работать иначе, чем то, что уже пробовал Фауст? –

+1

@Rob: ну, во-первых, это не приводит к синтаксической ошибке. Как говорит Эве в своем ответе, вы можете это исправить, добавив первую двоеточие к первой замене. Хаос делает два регулярных выражения проще, объединяя их в класс символов. – Telemachus

+0

Когда я использую то, что вы предложили, я получаю: vlc.plugin.path = C: \\ Program Files \\ JekyllV0.9.2 \\\\ VLC_1.0.0 \\\\ плагины Есть ли способ избежать изменения существующего "\\" на "\\\\"? –

3

Я уверен, что Perl слепо объединяющее все свои -e аргументы, так что те, в настоящее время сжато в s#\\#\\\\#gs#/#\\\\#g, а затем второе регулярное выражение выглядит как комментарий.

Это работает для меня, если я изменю его на -e 's#\\#\\\\#g; s#/#\\\\#g'.

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

0
[21:09:00][[email protected]:~]$ perl -pe 's#\/#\/\/#g; s#\\#\\\\#g' test.txt 
vlc.plugin.path = C:\\Program Files\\JekyllV0.9.2//VLC_1.0.0//plugins 
3

Это не работает, потому что Perl не обрабатывает два -e флагов - без запятой «между» двумя командами. Вы должны написать его, как показано ниже (если вы потеряете d-цитату сразу после «Perl», то есть.)

perl -p -i.orig -e "s#\\#\\\\#g;" -e "s#/#\\\\#g" %VIDEOLOG_PROPERTIES_FILE% 

я сделать что-то подобное, а потому, что Perl поддерживает '/' на PC, мое предпочтение отдается косые черты.Поэтому я использую следующее:

s![\\/]+!/!g; 

Таким образом, можно легко превратить вокруг

s![\\/]+!\\\\!g; 

Теперь слово о том, почему я, что: иногда люди не могут понять, должны ли они ставить косой чертой в начале или конце частей путей, которые будут объединены. Время от времени вы получаете даже двойные косые черты. (Но нет, если вы используете File::Spec.), Поэтому хорошо справляться с этими столкновениями. Тем более, что это будет путь, мы хотим взять хоть какое-то количество колючек любого рода и превратить их в то, что нам нравится.

Кроме того, я даже сделать это:

s!([\\/]+([.][\\/]+)?)+!/!g 

Поскольку он захватывает те случаи, когда это тот же кластер косых черт, разделенной точкой, которая ничего не делает, потому что путь мудрого / < =>(/+.)+ для этих программ и скрипты, которые обрабатывают точки в именах путей, тогда как другие программы будут выходить из строя.

+0

Это не совсем так. Perl обрабатывает два предложения '-e' просто отлично; то, что он не делает, это вставить неявную точку с запятой между ними. – chaos

+0

@chaos Вы абсолютно * правы, меня поразило, что я должен сказать Perl разместить там разделитель команд. Я всегда придерживался функционального предположения, что он не работает.Но я попробовал, и он работал на всех платформах, которые я пробовал. Благодаря! – Axeman

4

Вы хотите File::Spec->canonpath.

Обновление: Собственно, это была неправильная рекомендация. Это будет работать для внутренних вызовов функций и т. Д., Но оно будет писать одиночные обратные косые черты в файл. Тем не менее, следующий будет работать лучше:

#!/usr/bin/perl 

use strict; 
use warnings; 

use Config::INI::Reader; 

my $config = Config::INI::Reader->read_handle(\*DATA); 

my $var1 = $config->{_}->{'vlc.plugin.path1'}; 
my $var2 = $config->{_}->{'vlc.plugin.path2'}; 

for my $v ($var1, $var2) { 
    $v =~ s! (?: [\\]{1,2}) | (?:/) !\\\\!gx; 
    print "$v\n"; 
} 

__DATA__ 
vlc.plugin.path1 = C:\Program Files\JekyllV0.9.2\\VLC_1.0.0\\plugins 
vlc.plugin.path2 = C:\Program Files\JekyllV0.9.2/VLC_1.0.0/plugins 

Выход:

 
C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins 
C:\\Program Files\\JekyllV0.9.2\\VLC_1.0.0\\plugins 
+0

Спасибо. Это было очень поучительно и полезно. –

Смежные вопросы