Получение этого простого регулярного выражения для сопоставления в grep

2439
barlop

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

Это использует GnuWin32 grep. Не в Cygwin's grep.

C:\>echo "2 008abc.html" | grep -oiP \"2 [^.] grep: [^.]': No such file or directory  C:\>echo "2 008abc.html" | grep -oiP ^"2 [^.]  C:\>echo "2 008abc.html" | grep -oiP """2 [^.] grep: [^.]: No such file or directory  C:\>echo "2 008abc.html" | grep -oiP """2 0 grep: 0: No such file or directory  C:\>echo "2 008abc.html" | grep -oiP """"2 0" "2 0   C:\>echo "2 008abc.html" | grep -oiP """"2 [^.]"  C:\>echo "2 008abc.html" | grep -oiP """"2 0" "2 0 

(Я ответил на свой вопрос в предыдущей редакции, нет необходимости ссылаться на него, но это приводит к другой сильно связанной проблеме сопоставления, поэтому я изменил этот вопрос, чтобы сопоставить что-то очень похожее, но столкнулся с проблемой.)

-2

2 ответа на вопрос

2
juggler

Похоже, что вы используете Windows Command Prompt ( cmd.exe) в качестве оболочки и вас запутывают соглашения о цитировании или их отсутствие. Если я запускаю вашу команду в оболочке Fedora 15 Bash, она работает. Если я запускаю его в Windows, используя оболочку Cygwin Bash, это работает.

Чтобы заставить его работать cmd.exe, вы должны изменить кавычки и интервал. Я запустил приведенные ниже команды в cmd.exeWindows 7. Обратите внимание, как я изменил кавычки в команде grep, чтобы использовать одинарные кавычки вместо двойных кавычек, и перед pipe ( |) нет пробела .

Я использую Cygwin-версию GNU grep, которая должна вести себя так же, как ваша Win32 GNU grep.

c:\>c:\cygwin\bin\grep --v GNU grep 2.6.3  Copyright (C) 2009 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.  c:\>echo "2008abc.html"| c:\cygwin\bin\grep -oiP '\"[^.]' "2 

Если перед трубой есть пробел, пробел будет отражен через конвейер, и grep будет соответствовать ему. Это связано с идиотским поведением разбора cmd.exe.

c:\>echo "2008abc.html" | c:\cygwin\bin\grep -oiP '\"[^.]' "2 " 

Для вашего же здоровья посмотрите, можете ли вы использовать Cygwin's Bash или любую другую оболочку с разумными и последовательными соглашениями о цитировании.

как соглашения о цитировании окон не являются разумными или последовательными? barlop 12 лет назад 0
а в чем проблема с одинарными и двойными кавычками? Кстати, ваша строка работала '\ "[^.]' barlop 12 лет назад 0
Я не знаю, почему он работает с одинарными кавычками, а не с двойными, но работает в любом случае, если вы используете командную оболочку bash вместо cmd.exe. Я видел достаточно странных проблем с цитированием и пробелами в cmd.exe, что я избегаю его и использую Cygwin Bash, когда это возможно. juggler 12 лет назад 0
@barlop: Различия заключаются в том, что в Windows программа сама должна анализировать свою командную строку (в Unix это выполняется оболочкой: sh или bash; в Cygwin это выполняется средой выполнения cygwin1.dll), а в Windows используется \ как разделитель пути (bash рассматривает его как escape-символ). Многие проблемы возникают при использовании программ Cygwin с именами путей в стиле Windows. (Например, как должен анализироваться последний \ in "C: \ WINDOWS \"? Должен ли он работать по-разному в Cygwin и родной программе Windows?) grawity 12 лет назад 0
Проблемы с использованием @ dir \ prog для cygwin и / dir / prog для windows - это просто глупость пользователя, а не то, что должен делать технический специалист, я не спрашиваю о такой проблеме. Что касается последней косой черты, я не вижу, как это проблема, но проблема с ней в стороне, разве * nix также не имеет вопроса последней косой черты или нет. Я заметил, что в cygwin "echo * /" ставит косую черту после каждого имени каталога. Принимая во внимание, что «echo *» не ставит косую черту после любого имени каталога. И * nix интерпретирует CD Z /, а также CD Z barlop 12 лет назад 0
Это * полностью * не было моей целью. grawity 12 лет назад 0
@grawity Хорошо, что вы имеете в виду, когда говорите " программы Cygwin с путями в стиле Windows". ? barlop 12 лет назад 0
@barlop: `grep -r foo" C: \ Documents and Settings \ Simon Travaglia \ "` из оболочки Windows cmd.exe. Окончательный обратный слеш действует как разделитель пути? Или он экранирует `" `? Аналогично для` \ D`, `\ S`. Другой пример:` somecommand "funky \" символы "` - это один аргумент * `фанки 'символов` * или два аргумента * `фанки \` * и * `персонажи` *? grawity 12 лет назад 0
@barlop: Еще одно: `cmd / c somecommand" foo bar "`, в которой все, что после `/ c`, читается как один аргумент, несмотря на то, что оно не заключено в кавычки. Вот тут-то и возникает несоответствие. Для сравнения, в bash существует строгий набор правил, по которым каждая строка ввода анализируется одинаково. grawity 12 лет назад 0
@gordoco Извините, gordoco, я отменил ваш ответ, я только что понял, что вы ответили на него за grep cygwin, и вы сделали странную вещь, вызвав его из CMD.EXE, обычно команды cygwin выполняются внутри самого cygwin, как, например, вызов cygwin.bat первый. По совпадению, я замечаю эхо "2008abc.html" | grep -oiP \ "[^.] <- работает, вы ошиблись, я думаю, думая, что они работали одинаково в том, что одинарные кавычки не сделают это для gnuwin32, поэтому ваш ответ не сделал это для gnuwin32, вот что Я спрашивал о. barlop 12 лет назад 0
@grawity Я вижу, что вы имеете в виду, что cmd / c dir ab, принимает его как cmd / c "dir ab" и не терпит неудачу, как runas, если параметр программы содержал пробелы и не был заключен в кавычки, но любая программа запускается в Приглашение cmd может объединить все параметры в один. ни одна из программ linux тоже не может этого сделать? или объединить их или разделить их, как хочет, и, следовательно, также быть "противоречивым"? barlop 12 лет назад 0
@ barlop: не всегда. В оболочках Unix вы можете использовать `foobar`,` "foobar" `,` 'foobar'`, `" fo "ob'ar'`, но * shell * обрабатывает разбиение слов и то, что оно передает execv ( ) и то, что программа получает в argv [], всегда будет одной и той же 6-байтовой строкой * `foobar` *. Если вы введете `" foo bar "`, у вас будет argv [1] как * `foo bar` *. Если вы наберете `" foo "" bar "`, у вас будет argv [1] как * `foo` * и argv [2] как *` bar` *. Для сравнения, программы Win32 всегда получают одну * единственную * строку от GetCommandLine (), и вся деквотирование выполняется самой программой - если это вообще делается. grawity 12 лет назад 0
@barlop: Продолжаем с моего примера с именем файла. В оболочках Unix, если у вас есть строка в двойных кавычках и вы используете обратную косую черту, обратная косая черта всегда будет обрабатываться одинаково: экранирование для последующего символа. Оболочка применяет одинаковые правила ко всем командам. В Windows, поскольку программы делают это сами, в одних местах они могут рассматриваться как побег, а в других - как разделитель пути. Снова рассмотрим следующую командную строку: `somecmnd" foo bar \ "baz" qux`. Предположим, вы находитесь в системе, которая использует \ в качестве разделителя пути. Как бы вы разбили командную строку на отдельные аргументы? grawity 12 лет назад 0
@ Grawity Я пытался http://pastebin.com/28Q2Wxxr, скомпилированный с TCC win32. И работает он скомпилирован в Cygwin с GCC. значения в argsv кажутся одинаковыми между окнами и * nix. и это сокращает его. Из того, что я слышал, это правда, что в отличие от * nix-программ, программы на Win32 C выдаются в виде одной строки, но этого не видно, так как она разделяется (и кажется, что она удалена) даже до запуска основного метода. Таким образом, до сих пор не видно, где возникает место для несоответствия по сравнению с * nix программами. barlop 12 лет назад 0
(скоро проверим / подумаем о ваших дальнейших комментариях) barlop 12 лет назад 0
@grawwity Вы можете использовать \\ для буквального \, и \ "для буквального кавычки. Я думаю, вы знаете это, хотя .. Я не совсем уверен, что вы подразумеваете под системой, которая использует \ как разделитель пути, единственный Системы, с которыми я знаком, это Windows и, в некоторой степени, Unix, и в случае Windows, конечно, используется \ внутри путей, поэтому я могу упустить из виду вашу точку зрения. barlop 12 лет назад 0
Давайте [продолжим это обсуждение в чате] (http://chat.stackexchange.com/rooms/1325/discussion-between-grawity-and-barlop). grawity 12 лет назад 0
0
barlop

Это решение.

C:\>echo "2 008abc.html" | grep -oiP \"2" "[^.] "2 0 

Этот эксперимент помог (w is w.exe, который скомпилирован wc)

C:\>w \"2\ [^.] argv[0] = w argv[1] = "2\ argv[2] = [^.]  C:\>w \"2" "[^.] argv[0] = w argv[1] = "2 [^.]  C:\> 

Вот еще одно решение

C:\>echo "2 008abc.html" | grep -oiP "\"2 [^^.]" "2 0 

который, как вы можете видеть, я нашел после небольшого поворота, хотя нашел довольно быстро

W:\other>w "\"2 [^.]" argv[0] = w argv[1] = "2 [.]  W:\other>w "\"2 [\^.]" argv[0] = w argv[1] = "2 [\.]  W:\other>w "\"2 [^.]" argv[0] = w argv[1] = "2 [.]  W:\other>w "\"2 [^^.]" argv[0] = w argv[1] = "2 [^.] 

Туалет

#include <stdio.h>  int main(int argc, char *argv[]) { int i = 0; while (argv[i]) { printf("argv[%d] = %s\n", i, argv[i]); i++; } return 0; } 

Это полезно до wc. Вы можете использовать его, чтобы увидеть, что именно удаляет bash. хс

#include <stdio.h> #include <windows.h>  int main(int argc, char *argv[]) { printf(GetCommandLine()); return 0; } 

экс-

C:\>x & x C:\> C:\>x ^& x & C:\>