为什么 ls -R(向下递归)不适用于正则表达式
why the ls -R (recursing down) doesn't work with regular expression
在我的例子中,目录树如下
[peter@CentOS6 a]$ tree
.
├── 2.txt
└── b
└── 1.txt
1 directory, 2 files
为什么下面两条命令只能得到2.txt?
[peter@CentOS6 a]$ ls -R *.txt
2.txt
[peter@CentOS6 a]$ ls -R | grep *.txt
2.txt
您可以使用如下查找方式列出当前目录和子目录中所有匹配的文件
find . -name "*.txt"
在这两种情况下,您的 shell 在参数命中命令之前将 *.txt
扩展为 2.txt
。所以,你实际上是运行
ls -R 2.txt
ls -R | grep 2.txt
您不能告诉 ls
查找文件模式 - 这就是 find
的用途。在第二种情况下,您应该引用您的表达式并使用适当的正则表达式:
ls -R | grep '\.txt'
不清楚您问的 "why" 是指 "explain the output" 还是 "how should it be done"。 Steephen已经回答了后者,这是对前者的回答。
原因叫做"shell expansion"。当您在命令行中键入 *.txt 时,程序不会将其作为参数获取,而是 shell 展开它然后传递结果。
*.txt 扩展为 "all files in the current directory with arbitrarily many symbols in the beginning, ending with '.txt' and not starting with '.'".
这意味着当你输入“ls -R *.txt
”时,实际执行的命令是“ls -R 2.txt
”;当您执行“ls -R | grep *.txt
”时,它实际上执行“ls -R | grep 2.txt
”。
这就是 Steephen 在提供的答案中将通配符用引号引起来的确切原因。有必要停止这种扩张。事实上,您也可以使用单引号或在任何特殊字符前放置一个斜线。因此,以下任何一项都有效:
find . -name "*.txt"
或
find . -name '*.txt'
或
find . -name \*.txt
另一个还没有人提到的问题是,除了 shell 在 grep
看到它之前拦截 *
之外,shell 对待 *
不同于 grep
.
shell 使用文件 globbing,*
表示 "any number of characters"。
grep
使用正则表达式,*
表示"any number of the preceding item".
你需要做的是
ls -R | grep .\*\.txt
哪个会
- 转义
*
这样你的 shell 就不会拦截它
- 按照
grep
期望的方式正确格式化正则表达式
- 正确转义
.txt
中的 .
以确保您有文件扩展名
在我的例子中,目录树如下
[peter@CentOS6 a]$ tree . ├── 2.txt └── b └── 1.txt 1 directory, 2 files
为什么下面两条命令只能得到2.txt?
[peter@CentOS6 a]$ ls -R *.txt 2.txt [peter@CentOS6 a]$ ls -R | grep *.txt 2.txt
您可以使用如下查找方式列出当前目录和子目录中所有匹配的文件
find . -name "*.txt"
在这两种情况下,您的 shell 在参数命中命令之前将 *.txt
扩展为 2.txt
。所以,你实际上是运行
ls -R 2.txt
ls -R | grep 2.txt
您不能告诉 ls
查找文件模式 - 这就是 find
的用途。在第二种情况下,您应该引用您的表达式并使用适当的正则表达式:
ls -R | grep '\.txt'
不清楚您问的 "why" 是指 "explain the output" 还是 "how should it be done"。 Steephen已经回答了后者,这是对前者的回答。
原因叫做"shell expansion"。当您在命令行中键入 *.txt 时,程序不会将其作为参数获取,而是 shell 展开它然后传递结果。
*.txt 扩展为 "all files in the current directory with arbitrarily many symbols in the beginning, ending with '.txt' and not starting with '.'".
这意味着当你输入“ls -R *.txt
”时,实际执行的命令是“ls -R 2.txt
”;当您执行“ls -R | grep *.txt
”时,它实际上执行“ls -R | grep 2.txt
”。
这就是 Steephen 在提供的答案中将通配符用引号引起来的确切原因。有必要停止这种扩张。事实上,您也可以使用单引号或在任何特殊字符前放置一个斜线。因此,以下任何一项都有效:
find . -name "*.txt"
或
find . -name '*.txt'
或
find . -name \*.txt
另一个还没有人提到的问题是,除了 shell 在 grep
看到它之前拦截 *
之外,shell 对待 *
不同于 grep
.
shell 使用文件 globbing,*
表示 "any number of characters"。
grep
使用正则表达式,*
表示"any number of the preceding item".
你需要做的是
ls -R | grep .\*\.txt
哪个会
- 转义
*
这样你的 shell 就不会拦截它 - 按照
grep
期望的方式正确格式化正则表达式 - 正确转义
.txt
中的.
以确保您有文件扩展名