为什么ls | grep *不显示任何内容?

时间:2016-05-29 04:35:17

标签: bash command-line grep ls

如果我这样做,输出是: enter image description here

但如果我做ls | grep complex * 或ll | grep complex*甚至ll | grep *ll | grep * | less 输出总是: enter image description here

这让我很困惑。

我想获得以complex* FYI开头的所有文件的列表,如果' *' ==任何事情。

4 个答案:

答案 0 :(得分:3)

你正在寻找:

ls | grep 'complex.*'

或者,更好:

ls complex*

答案 1 :(得分:1)

默认*适用于[ globbing ]

如果您有一个名为*的文件或一个包含*的文件,您可以

ls | grep \*

ls | grep '*'

如果您要在文件中查找文字*

grep '*' *  # second will glob all the files in the current dir.

如果您想使用,请查看所有包含Complex _plus_something 一词的文件:

grep -E '\<Complex[_[:alnum:]]+' *  

此处+代表一个或多个,\<匹配单词开头的空字符串: - )

答案 2 :(得分:1)

为了简化我的解释,我不会谈论隐藏文件。

因为你的命令并不代表你想要实现的目标。

*对于bash非常特殊,并没有你想到的意思。 shell将替换为当前目录中可以对应的所有文件名。 一个例子:

adrien@adrienLT:~/foo$ ls
adrien@adrienLT:~/foo$ touch foo
adrien@adrienLT:~/foo$ ls
foo
adrien@adrienLT:~/foo$ ls | grep *
foo

%以上相当于 $ ls | grep foo

adrien@adrienLT:~/foo$ touch bar
adrien@adrienLT:~/foo$ ls | grep *

%以上相当于 $ ls | grep bar foo,如果单词&#34; bar&#34;是 IN 文件foo。

看那里有一个包含更多文件的例子:

adrien@adrienLT:~/foo$ touch bar foo foobar
adrien@adrienLT:~/foo$ echo "bar" > foo
adrien@adrienLT:~/foo$ echo "bar" > foobar
adrien@adrienLT:~/foo$ ls | grep *
foo:bar
foobar:bar

现在,为了实现您想要实现的目标,您可以使用*来发挥优势:

adrien@adrienLT:~/foo$ ls foo*
foo  foobar

但如果有一个与您的研究相对应的目录,它将列出其内容。

adrien@adrienLT:~/foo$ mkdir foodir
adrien@adrienLT:~/foo$ for i in {0..10}; do touch "foodir/$i"; done
adrien@adrienLT:~/foo$ ls foo*
foo  foobar

foodir:
0  1  10  2  3  4  5  6  7  8  9

因此,您可能希望使用选项-d来列出其内容:

adrien@adrienLT:~/foo$ ls -d foo*
foo  foobar  foodir

但如果您的搜索变得更复杂,我只能建议使用更强大的工具,例如find。

这个使用了globbing(*我在上面解释过)

adrien@adrienLT:~/foo$ find . -type f -name "foo*"
./foo
./foobar

这个使用正则表达式,但这是一个你需要学习的工具,能够处理而不会失去你的头发:

adrien@adrienLT:~/foo$ find . -type f -regex ".*/foo[^/]*$"
./foo
./foobar

为了解释一下,上面搜索当前目录(。)只搜索与特定模式匹配的文件(-type f)(-regex&#34;。 / foo [^ /] $&#34;。)

这个模式是&#34;任何事后跟斜杠foo后跟除了斜杠之外的任何东西,直到文件结束&#34;。

答案 3 :(得分:1)

你有两个错误:*并不代表正则表达式中的“任何东西”,而且因为你没有引用它,所以shell扩展了它。

如果您有三个文件,则在通配符扩展后ls | grep *的结果类似于

ls | grep bar baz foo

grep在这种情况下的行为是它只是忽略标准输入(这可能没有记录和/或完全标准和/或定义明确),因此ls |被忽略且无用。您最终会在另外两个文件中查找第一个匹配文件的名称。

现在,您使用的正则表达式在输入中的任意位置搜索complex*表示零次或多次出现x;如果有零,表达式将匹配,并且它不会阻止匹配,例如incomplete,所以你可能会省略这一点)。正确的表达式是^complex只能在行的开头找到这个单词(不要忘记引号; ^也是一个shell元字符)或只是complex才能在一个地方找到它线。

如果只是要枚举,您根本不需要grep或正则表达式,或ls

echo complex*

将显示所有匹配文件的名称,或者如果您想要每行一个,

printf '%s\n' complex*

(这也是更强大的,所以通常是一种更好的方法。如果可以,请避免在脚本中同时使用lsecho。)

要循环匹配文件,您无法可靠地使用ls

for f in complex*; do
    printf '%s\n' "$f"
done

作为一种特殊情况,grep '*'会查找文字星号。一些正则表达式工具(正确地)失败,并显示无效正则表达式的错误消息(包括* BSD grep;特殊情况在GNU grep)。