grep
在我的计算机上似乎已损坏。重新安装它没有帮助。重新启动也没有帮助。前两行创建一个包含任意文本的文件,输入以 control-D 字符终止。
ls -1
表示在一列中列出。示例如下...
> cat > file0.txt
asdf
> cp file0.txt file1.txt
> ls -1
file0.txt
file1.txt
> ls -1 | grep f*
>
在遇到此问题之前,我确实犯了一个错误,使用不匹配的引号调用了 grep,但我不明白这个问题如何在重启后继续存在。
不匹配的报价示例......
ls -1 | grep 'file* | wc
在这个例子中,目录列表通过管道传输到 grep,然后通过管道传输到行、字和字节计数器程序wc
。
答案1
grep f*
在你的情况下,表达式将grep file0.txt file1.txt
被 shell 扩展为。
file0.txt
显然文件file1.txt中没有行。
我知道这不是你想要的,但事情就是这样的。
:~$ mkdir test
:~$ cd test/
:~/test$ touch f1
:~/test$ touch f2
:~/test$ set -x
:~/test$ ls | grep f*
+ ls --color=auto
+ grep --color=auto f1 f2
答案2
grep
ls
没有以任何方式使用的输出。
当您在 shell 扩展为两个或更多参数的grep f*
情况下运行时,将除一个参数之外的所有参数视为要打开和读取的文件的名称。f*
grep
当grep
从命名文件读取时,从标准输入读取的默认行为不适用,因此它不会读取从另一个命令传送给它的数据。
您的grep
程序没有损坏,并且您观察到的行为是正确的和预期的行为,这就是为什么重新安装grep
和重新启动不会改变它的原因。详细信息如下。
grep f*
没有将参数传递f*
给 grep。
grep
从来没见过这段文字f*
。作为索伦A 说,f*
是一个 glob。shell 对 glob 进行了特殊处理。因为f*
没有引,shell 将其扩展为当前目录中以 开头的文件的名称。每个这样的名称都作为单独的参数f
传递给。(grep
这种外壳扩展也称为通配符、文件名扩展和路径名扩展。
根据您的描述,恰好有两个文件与 glob 匹配f*
:file0.txt
和file1.txt
。由于它们是当前目录中仅有的两个名称以 开头的文件,因此从运行f
传递给的命令行参数是grep
grep f*
一模一样和运行 时传递给它的那些一样grep file0.txt file1.txt
。如果你要将更多这样的文件添加到目录中,那么grep f*
将传递超过这两个文件名作为 的参数给grep
,但file0.txt
和file1.txt
仍然会包含在其中。
您将ls
输出通过管道传输grep
到grep
没有从管道读取。
一根管道连接标准输出一个命令标准输入另一个。cat
与许多其他命令一样,grep
以两种方式接受输入:
您可以将文件名作为命令行参数传递给它,它将从这些文件中读取。 的第一个非选项参数
grep
是模式,但后续的非选项参数将被视为将从中获取输入的文件名。(您不会尝试将多个模式传递给
grep
,但如果您这样做,则可以使用选项-e
,其操作数始终被视为模式。)您可以不传递文件名参数,它将从自己的标准输入中读取。这是管道到 有效的情况
grep
。只有在缺席grep
完全从标准输入读取的文件名参数。这就是为什么可以使用
grep
来搜索一个或多个文件,而无需阻塞并等待您在终端中输入输入。当您通过管道连接到 时grep
,对于 来说毫无意义的额外输入grep
来自管道左侧的命令,而不是来自您的终端。grep
仍然不使用它,这是一件好事。(您并不是想
grep
除了读取一个或多个命名文件之外还读取标准输入,但是如果您这样做了,则可以将参数传递给它-
。)
因为当前目录中有两个文件的名称以 开头f
,所以 globf*
扩展为两个参数。第一个参数file0.txt
用作图案。第二个,file1.txt
,用于命名输入文件。由于grep
给出了指定输入文件的参数,因此上述两种情况中的第一种适用(“您可以将文件名作为命令行参数传递给它”)。因此grep
永远不会从标准输入读取,也永远不会使用 的输出ls
。
答案3
ls | grep 'f*'
是糟糕的形式。
ls f*
应优先考虑。
当使用更复杂的正则表达式模式时,请切换到egrep
/ grep -E
。
当我在这里时,cat
很少需要。 tac
比有用 100 倍cat
。cat
滥用是类 Unix 系统上的一个严重问题。;)
答案4
*
是一个特殊字符,通常被解释为新命令/指令。您需要\
在它前面放置一个:
ls -1 | grep f\*
但是,您可能想要的是获取以 开头的所有文件,f
而不是所有包含 的文件,f
因此请改用另一个特殊字符:
ls -1 | grep ^f
指示^
grep 查找以 开头的行f
。