Reputation: 113
In my case, the directory tree is following
[peter@CentOS6 a]$ tree . ├── 2.txt └── b └── 1.txt 1 directory, 2 files
why the following two command does only get 2.txt?
[peter@CentOS6 a]$ ls -R *.txt 2.txt [peter@CentOS6 a]$ ls -R | grep *.txt 2.txt
Upvotes: 2
Views: 179
Reputation: 2068
The other problem that nobody has mentioned yet is that, beyond the fact that the shell intercepts the *
before grep
sees it, the shell treats *
differently from grep
.
The shell uses file globbing, and *
means "any number of characters".
grep
uses regular expressions, and *
means "any number of the preceding item".
What you need to do is
ls -R | grep .\*\\.txt
which will
*
so your shell does not intercept itgrep
expects.
in .txt
to ensure that you have file extensionsUpvotes: 1
Reputation: 5858
It isn't clear if you are asking "why" meaning "explain the output" or "how should it be done". Steephen has already answered the latter, this is an answer to the former.
The reason for that is called "shell expansion". When you type *.txt in the command line, the program doesn't get it as a parameter, but rather the shell expands it and then passes the results.
*.txt expands to be "all files in the current directory with arbitrarily many symbols in the beginning, ending with '.txt' and not starting with '.'".
This means that when you type "ls -R *.txt
" the command that actually executes is "ls -R 2.txt
"; and when you do "ls -R | grep *.txt
" it actually executes "ls -R | grep 2.txt
".
This is the exact reason why Steephen has put quotation marks around the wildcard in the answer provided. It is necessary to stop this expansion. In fact you could also do so with single quotes or by placing a slash before any special character. Thus any of the following will work:
find . -name "*.txt"
or
find . -name '*.txt'
or
find . -name \*.txt
Upvotes: 1
Reputation: 179592
In both cases, your shell is expanding *.txt
into 2.txt
before the argument hits the command. So, you are in effect running
ls -R 2.txt
ls -R | grep 2.txt
You can't tell ls
to look for a file pattern - that's what find
is for. In the second case, you should quote your expression and use a proper regex:
ls -R | grep '\.txt'
Upvotes: 3
Reputation: 15824
You can use find as follows to list all matching files in current and sub directories
find . -name "*.txt"
Upvotes: 2