Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I want to match a quote, 2, a space, and any character that is not a literal dot.

This is using GnuWin32 grep. Not 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

(I have answered my own question in its prior revision, no need to refer to it, but it leads to another strongly related matching problem, so I've revised this question to matching something very similar, but running into a problem.)

share|improve this question

2 Answers 2

It looks like you're using Windows Command Prompt (cmd.exe) as your shell, and you're getting tripped up by its quoting conventions, or lack thereof. If I run your command in Fedora 15 Bash shell, it works. If I run it in Windows using Cygwin's Bash shell, it works.

To get it to work with cmd.exe, you have to change the quotes and spacing. I ran the commands below in cmd.exe on Windows 7. Note how I changed the quotes on the grep command to use single quotes instead of double quotes, and there is no space before the pipe (|).

I am using the Cygwin version of GNU grep, which should behave the same as your 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 '\"[^.]'

If there is a space before the pipe, the space will be echoed through the pipeline and grep will match it. This is due to the idiotic parsing behavior of cmd.exe.

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

For your own sanity, see if you can use Cygwin's Bash or any other shell with reasonable and consistent quoting conventions.

share|improve this answer
how is the windows quoting conventions not reasonable or consistent? –  barlop Aug 27 '11 at 3:24
and what is the issue with single quotes and double quotes? btw, your line worked '\"[^.]' –  barlop Aug 27 '11 at 3:30
I don't know why it works with single quotes and not with double quotes, but it works fine either way if you use bash shell instead of cmd.exe. I've seen enough weird issues with quoting and spacing in cmd.exe that I avoid it and use cygwin bash whenever possible. –  cantfork Aug 27 '11 at 4:04
@barlop: The differences are that in Windows the program has to parse its command line itself (in Unix this is done by the shell: sh or bash; in Cygwin this is done by the cygwin1.dll runtime), and that Windows uses \ as a path separator (bash treats it as an escape character). Many problems appear when you use Cygwin programs with Windows-style path names. (For example, how should the last \ in "C:\WINDOWS\" be parsed? Should it work differently in Cygwin and a native Windows program?) –  grawity Aug 27 '11 at 16:41
@grawity well problems of using \dir\prog for cygwin, and /dir/prog for windows, are purely the sillyness of the user and not things that a techie would do, i'm not asking about that kind of problem. As to the last slash, I don't see how it's a problem, but problem with it aside, doesn't *nix also have that question of last slash or not. I notice in cygwin "echo */" puts a slash after every directory name. Whereas "echo *" doesn't put a slash after any directory name. And *nix interprets cd z/ as well as cd z –  barlop Aug 27 '11 at 20:33
up vote 0 down vote accepted

This is a solution.

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

This experimentation helped (w is w.exe, which is w.c compiled)

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

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


Here is another solution

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

which as you can see I found after a little fiddling, though found pretty quickly

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]);
    return 0;
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.