输入重定向到 grep
Input redirection to grep
我有一个包含如下内容的目录 -
vishal.yadav@droid36:~/Shell$ ls
lazy_dog.txt ls-error.txt ls-output.txt ShellCommands.txt TheTimeMachineHGWells.txt words.txt words.txt.bak
第一个命令
如果我尝试使用 ls | grep *.txt
我会得到以下输出 -
ShellCommands.txt: $ cat > lazy_dog.txt
ShellCommands.txt: $ cat lazy_dog.txt
ShellCommands.txt: $ cat < lazy_dog.txt
ShellCommands.txt:input from the keyboard to the file lazy_dog.txt. We see that the result is the
第二个命令
如果我使用 ls | grep .*.txt
我得到这个作为输出 -
lazy_dog.txt
ls-error.txt
ls-output.txt
ShellCommands.txt
TheTimeMachineHGWells.txt
words.txt
words.txt.bak
.*.txt
和*.txt
不是一回事吗?
在第一个命令中,ls
的输出是regex
for grep
还是list of files
?
同样,对于第二个命令,ls
的输出是regex
还是list of files
?
做ls -al
:
你会发现当前目录被列为 .
而上一个目录被列为 ..
.
因此,当您说 ls | grep .*.txt
时,.
被视为从包含 .txt
的当前目录匹配的路径。
grep 将模式 .*.txt
视为正则表达式,而不是 glob。
所以你可以使用ls *.txt
或ls | grep .*txt
在第一个命令 (ls | grep *.txt
) 中,ls
的输出被 grep
完全忽略,因为它看到:
grep lazy_dog.txt ls-error.txt ls-output.txt ShellCommands.txt TheTimeMachineHGWells.txt
它有一个模式 lazy_dog.txt
和四个文件,因此它依次读取每个文件以找到模式,并在匹配的输出行前加上包含该模式的文件名作为前缀。如果只有一个文件名,则不会在匹配行之前列出文件名。
似乎 grep
搜索的四个文件(ls-error.txt
、ls-output.txt
、ShellCommands.txt
、TheTimeMachineHGWells.txt
)中唯一包含文本的文件lazy_dog.txt
是 ShellCommands.txt
,所以这就是您在输出中看到的内容。请注意,包含 lazy_dogstxt
的行也将匹配正则表达式(但不匹配 shell glob)。
在第二个命令(ls | grep .*.txt
)中,没有匹配.*.txt
的文件,因此该参数未扩展地传递给grep
,所以它只有一个模式,所以它读取它的标准输入,这是这次 ls
的输出。所有文件名都匹配正则表达式 .*.txt
(即使其中 none 匹配 shell glob .*.txt
),所以它们都被列出了。请注意,它还会拾取许多其他行,即使是只包含 "etxt" 的行,因为 .
是一个 grep
元字符(并且 .*.txt
正则表达式匹配任何零字符串或多个字符后跟一个任意字符,然后是 txt
.
我有一个包含如下内容的目录 -
vishal.yadav@droid36:~/Shell$ ls
lazy_dog.txt ls-error.txt ls-output.txt ShellCommands.txt TheTimeMachineHGWells.txt words.txt words.txt.bak
第一个命令
如果我尝试使用 ls | grep *.txt
我会得到以下输出 -
ShellCommands.txt: $ cat > lazy_dog.txt
ShellCommands.txt: $ cat lazy_dog.txt
ShellCommands.txt: $ cat < lazy_dog.txt
ShellCommands.txt:input from the keyboard to the file lazy_dog.txt. We see that the result is the
第二个命令
如果我使用 ls | grep .*.txt
我得到这个作为输出 -
lazy_dog.txt
ls-error.txt
ls-output.txt
ShellCommands.txt
TheTimeMachineHGWells.txt
words.txt
words.txt.bak
.*.txt
和*.txt
不是一回事吗?
在第一个命令中,ls
的输出是regex
for grep
还是list of files
?
同样,对于第二个命令,ls
的输出是regex
还是list of files
?
做ls -al
:
你会发现当前目录被列为 .
而上一个目录被列为 ..
.
因此,当您说 ls | grep .*.txt
时,.
被视为从包含 .txt
的当前目录匹配的路径。
grep 将模式 .*.txt
视为正则表达式,而不是 glob。
所以你可以使用ls *.txt
或ls | grep .*txt
在第一个命令 (ls | grep *.txt
) 中,ls
的输出被 grep
完全忽略,因为它看到:
grep lazy_dog.txt ls-error.txt ls-output.txt ShellCommands.txt TheTimeMachineHGWells.txt
它有一个模式 lazy_dog.txt
和四个文件,因此它依次读取每个文件以找到模式,并在匹配的输出行前加上包含该模式的文件名作为前缀。如果只有一个文件名,则不会在匹配行之前列出文件名。
似乎 grep
搜索的四个文件(ls-error.txt
、ls-output.txt
、ShellCommands.txt
、TheTimeMachineHGWells.txt
)中唯一包含文本的文件lazy_dog.txt
是 ShellCommands.txt
,所以这就是您在输出中看到的内容。请注意,包含 lazy_dogstxt
的行也将匹配正则表达式(但不匹配 shell glob)。
在第二个命令(ls | grep .*.txt
)中,没有匹配.*.txt
的文件,因此该参数未扩展地传递给grep
,所以它只有一个模式,所以它读取它的标准输入,这是这次 ls
的输出。所有文件名都匹配正则表达式 .*.txt
(即使其中 none 匹配 shell glob .*.txt
),所以它们都被列出了。请注意,它还会拾取许多其他行,即使是只包含 "etxt" 的行,因为 .
是一个 grep
元字符(并且 .*.txt
正则表达式匹配任何零字符串或多个字符后跟一个任意字符,然后是 txt
.