Obtendo esta expressão regular simples para combinar no grep


-2

Eu quero combinar uma citação 2, um espaço e qualquer caractere que não seja um ponto literal.

Isso está usando GnuWin32 grep. Não 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

(Eu respondi a minha própria pergunta em sua revisão anterior, não há necessidade de se referir a ela, mas isso leva a outro problema de correspondência fortemente relacionado, então eu revisei essa questão para combinar algo muito semelhante, mas encontrei um problema.)

Respostas:


2

Parece que você está usando o prompt de comando do Windows ( cmd.exe ) como o seu shell, e você está ficando desarmado por suas convenções de cotação, ou a falta dela. Se eu executar o seu comando em Fedora 15 Bash shell, funciona. Se eu executá-lo no Windows usando o shell Bash do Cygwin, ele funciona.

Para fazê-lo funcionar com cmd.exe, você tem que alterar as cotações e espaçamento. Eu corri os comandos abaixo em cmd.exe no Windows 7. Observe como alterei as aspas no comando grep para usar aspas simples em vez de aspas duplas e não há espaço antes do pipe ( | ).

Eu estou usando a versão Cygwin do GNU grep, que deve se comportar da mesma forma que o seu 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

Se houver um espaço antes do pipe, o espaço será ecoado pelo pipeline e o grep corresponderá a ele. Isto é devido ao comportamento de análise idiota de cmd.exe.

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

Para sua própria sanidade, veja se você pode usar o Cygwin's Bash ou qualquer outro shell com convenções de cotação razoáveis ​​e consistentes.


Como as convenções de cotações do Windows não são razoáveis ​​ou consistentes?
barlop

e qual é o problema com aspas simples e aspas duplas? btw, sua linha funcionou '\ "[^.'
barlop

Eu não sei porque funciona com aspas simples e não com aspas duplas, mas funciona bem de qualquer forma se você usar o shell bash em vez de cmd.exe. Eu vi bastante problemas estranhos com citações e espaçamento em cmd.exe que eu evito e uso cygwin bash sempre que possível.
juggler

@barlop: As diferenças são que no Windows o programa tem que analisar sua própria linha de comando (no Unix isso é feito pelo shell: sh ou bash; no Cygwin isso é feito pelo tempo de execução do cygwin1.dll), e o Windows usa \ como um separador de caminho (o bash o trata como um caractere de escape). Muitos problemas aparecem quando você usa programas Cygwin com nomes de caminho no estilo do Windows. (Por exemplo, como o último \ em "C: \ WINDOWS \" deve ser analisado? Deve funcionar de forma diferente no Cygwin e em um programa nativo do Windows?)
grawity

@grawity bem problemas de usar \ dir \ prog para cygwin, e / dir / prog para windows, são puramente a bobagem do usuário e não coisas que um técnico faria, eu não estou perguntando sobre esse tipo de problema. Quanto à última barra, não vejo como é um problema, mas problema com isso de lado, não * nix também tem essa questão da última barra ou não. Eu observei no cygwin "echo * /" coloca uma barra após cada nome de diretório. Considerando que "echo *" não coloca uma barra após qualquer nome de diretório. E o * nix interpreta o cd z / bem como o cd z
barlop

0

Esta é uma solução.

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

Essa experimentação ajudou (w é w.exe, que é compilado por w.c)

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

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

C:\>

Aqui está outra solução

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

que, como você pode ver, encontrei depois de um pouco de brincadeira, embora tenha sido encontrado rapidamente

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 [^.]

banheiro

#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;
}

este é útil antes de w.c Você pode usá-lo para ver exatamente o que o bash remove. x.c

#include <stdio.h>
#include <windows.h>

int main(int argc, char *argv[]) {
    printf(GetCommandLine());
    return 0;
}

ex-

C:\>x &
x
C:\>
C:\>x ^&
x  &
C:\>
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.