Ottenere questa semplice espressione regolare per abbinare in grep


-2

Voglio abbinare una citazione, 2uno spazio e qualsiasi personaggio che non sia un punto letterale.

Questo sta usando GnuWin32 grep. Non il grep di Cygwin .

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

(Ho risposto alla mia domanda nella sua precedente revisione, non è necessario fare riferimento ad essa, ma porta a un altro problema di corrispondenza fortemente correlato, quindi ho modificato questa domanda per abbinare qualcosa di molto simile, ma ho riscontrato un problema.)

Risposte:


2

Sembra che tu stia usando il prompt dei comandi di Windows ( cmd.exe) come shell, e ti stai facendo inciampare dalle sue convenzioni di quotazione o dalla sua mancanza. Se eseguo il tuo comando in Fedora 15 Bash shell, funziona. Se lo eseguo in Windows usando la shell Bash di Cygwin, funziona.

Per farlo funzionare cmd.exe, devi cambiare le virgolette e la spaziatura. Ho eseguito i comandi di seguito in cmd.exeWindows 7. Nota come ho cambiato le virgolette sul comando grep per usare virgolette singole anziché doppie, e non c'è spazio prima di pipe ( |).

Sto usando la versione Cygwin di GNU grep, che dovrebbe comportarsi come la tua GNU grep Win32.

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 c'è uno spazio prima della pipe, lo spazio verrà ripetuto attraverso la pipeline e grep lo abbinerà. Ciò è dovuto al comportamento di analisi idiota di cmd.exe.

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

Per la tua sanità mentale, vedi se puoi usare Cygwin's Bash o qualsiasi altra shell con convenzioni di quotazione ragionevoli e coerenti.


in che modo le citazioni di Windows non sono ragionevoli o coerenti?
barlop

e qual è il problema con virgolette singole e doppie virgolette? tra l'altro, la tua linea ha funzionato '\ "[^.]'
barlop

Non so perché funziona con virgolette singole e non con virgolette doppie, ma funziona bene in entrambi i casi se si utilizza la shell bash invece di cmd.exe. Ho visto abbastanza strani problemi con la quotazione e la spaziatura in cmd.exe che lo evito e utilizzo cygwin bash ogni volta che è possibile.
giocoliere

@barlop: Le differenze sono che in Windows il programma deve analizzare la riga di comando stessa (in Unix questo è fatto dalla shell: sh o bash; in Cygwin questo è fatto dal runtime cygwin1.dll) e che Windows usa \ come separatore di tracciato (bash lo considera un personaggio di fuga). Molti problemi compaiono quando si utilizzano programmi Cygwin con nomi di percorso in stile Windows. (Ad esempio, come deve essere analizzato l'ultimo \ in "C: \ WINDOWS \"? Dovrebbe funzionare diversamente in Cygwin e in un programma Windows nativo?)
Grawity

I problemi di @grawity nell'uso di \ dir \ prog per cygwin e / dir / prog per windows, sono puramente la sciocchezza dell'utente e non cose che farebbe un tecnico, non sto chiedendo quel tipo di problema. Per quanto riguarda l'ultima barra, non vedo come sia un problema, ma a parte questo, non * * nix ha anche quella domanda sull'ultima barra o no. Ho notato in cygwin "echo * /" una barra dopo ogni nome di directory. Considerando che "echo *" non inserisce una barra dopo qualsiasi nome di directory. E * nix interpreta cd z / così come cd z
barlop il

0

Questa è una soluzione

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

Questa sperimentazione ha aiutato (w is w.exe, che è compilato wc)

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

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

C:\>

Ecco un'altra soluzione

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

che, come puoi vedere, ho trovato dopo aver giocherellato un po ', anche se ho trovato abbastanza 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 [^.]

bagno

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

questo è utile prima di wc Puoi usarlo per vedere esattamente cosa rimuove bash. xc

#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:\>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.