0

In Bash, when you type ls *.out, it will output the list which ended with .out. Is this a regular expression?

If yes; when I echo a.out > test and then type grep *.out test, it outputs nothing.

Is * in the ls same * in the regex?

a2f0
  • 1,615
  • 2
  • 19
  • 28
Courage
  • 543
  • 5
  • 25
  • 1
    Check these posts: http://stackoverflow.com/questions/23702202/what-are-the-differences-between-glob-style-pattern-and-regular-expression and http://stackoverflow.com/questions/19673427/whats-the-difference-between-and-in-regular-expressions – codeforester May 15 '17 at 04:20
  • thanks, that sound my ally. – Courage May 15 '17 at 05:27

5 Answers5

1

If you want to search in all files ending in .out, try grep <string> *.out.

You also may want to read up on globbing.

a2f0
  • 1,615
  • 2
  • 19
  • 28
1

The main thing to understand is that your shell is expanding program arguments (passed to main function of executed programs). Read Bash chapter about shell expansions (and globbing)

So you should not type ls "*.out" but just ls *.out then the /bin/ls program is started with the expansion of *.out. For example, if you have files a.out, b.out, cc.out, a.c the expansion of *.out (done by the shell) is a.out b.out cc.out so /bin/ls gets "ls" "a.out" "b.out" "cc.out" followed by NULL as its char**argv second argument to its main, with the first int argc argument being 4.

But grep indeed want some regular expression or "regexp". You generally want to quote it (to avoid the shell to try its expansion).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

It's the shell that expands the filename globs, so in both ls *.out and grep *.out test the shell fills the filenames to the command line, and the command itself only sees the resulting list of names. Assuming you have files called foo.out and bar.out, those commands would be equivalent to these:

ls bar.out foo.out
grep bar.out foo.out test

The first one asks ls to list the files, the second asks grep to look for the pattern bar.out in the files foo.out and test. The latter is probably not what you want, so quote the pattern for grep:

grep "*.out" test

Except that that is not really a valid regular expression. In filename globs, the asterisk * matches zero or more characters, in regular expression it matches zero or more of the previous item (character, character group or expression in parenthesis), but at the start of line there aren't any, so the expression makes little sense. Perl complains about that, grep and sed don't, but they also don't seem to match anything.

In regexes, the dot . means any character, so needs to be escaped to be taken literally. Also, grep finds matches anywhere in the line, so the leading .* (which would match any number of any characters) can be omitted. So this would look for lines containing the string .out in the file test:

grep "\.out" test

As we saw, the patterns used by Bash and the patterns (regular expressions) used by grep are not the same. See e.g. Bash's manual for the pattern matches used in filename expansion and the man page regex(7) for regular expressions. Also note that there are different dialects of regexes, which aren't fully compatible with each other.

ilkkachu
  • 6,221
  • 16
  • 30
0

By default, grep looks for the exact expression, not a regular expression, but you can tell it to look for a regular expression by adding the -E flag.

So I think what you're looking for is grep -E *.out test, though a little bit of research on the net would've given you what you wanted ;)

TuringTux
  • 559
  • 1
  • 12
  • 26
  • thanks, but immediately-preceding * is nothing, what does the ' * ' is really match? – Courage May 14 '17 at 15:26
  • 3
    No, by default `grep` looks for a match to a basic regular expression (BRE), `grep -F` (or `fgrep`) looks for a fixed string, and `grep -E` (or `egrep`) looks for an extended regular expression. GNU grep's man page mentions the difference between those in brief: http://man7.org/linux/man-pages/man1/grep.1.html – ilkkachu May 14 '17 at 15:39
0
  1. For grep command, * means 0 or more occurences of prev/preceding character or expression. So in your case grep .out* test would work as it will look for the occurrence of .ou followed by 0 or more occurrence of any character in the file test.

  2. For ls command, ls *.out would mean list all the files/folders ending with their name as .out.

YunujD
  • 74
  • 5
  • the regex `.out*` would look for `ou` following any character, e.g. `bout`, `sou` or `~ou` (it would also match any number of `t`'s after that, but with regular grep, it means little.) – ilkkachu May 14 '17 at 15:44
  • Thanks ikkikachu! That makes much more sense. I'll edit my answer. – YunujD May 14 '17 at 16:27