在最近的 Ubuntu 版本中查找和 bash 问题

Car*_*ger 2 bash 11.04 grep

在过去六个月左右的时间里,我在 bash 中组合搜索时遇到了问题。确切的示例与 Python 编程有关,但适用于任何类型的检测/操作。

假设我想要我所在目录中所有 Python 文件的列表。这很简单:

find . -name '*.py'
Run Code Online (Sandbox Code Playgroud)

现在,假设我只对那些包含字符串“psycopg”的 Python 文件感兴趣,例如因为我想从旧的 PostgreSQL 访问库psycopg 转换psycopg2。还是很简单的:

grep -l  psycopg `find . -name '*.py'`
Run Code Online (Sandbox Code Playgroud)

现在,假设我想列出这些文件的完整列表,以检查它们的日期戳以查看我上次接触它们的时间。我也希望在 gedit 中打开它们,但让我们坚持以下列表:

ls -l `!!`
Run Code Online (Sandbox Code Playgroud)

扩展到

ls -l `grep -l  psycopg `find . -name '*.py'``
Run Code Online (Sandbox Code Playgroud)

现在,会发生什么?答:没什么。bash 提示只是挂起。这是为什么?这可能是一种错误的做事方式,但它曾经奏效。我很确定它可以在 Ubuntu 10.10 或 10.04 之前运行。

小智 6

问题是带有反引号的嵌套命令替换。bash首先尝试执行grep -l psycopg(在前两个反引号之间)。但是没有文件名 - 因此它需要输入stdin(您可以通过输入来尝试psycopg)。

您可以通过使用$(command)命令替换的语法来避免此问题:

grep -l  psycopg $(find . -name '*.py')
ls -l $(!!)
Run Code Online (Sandbox Code Playgroud)

在这种情况下,它可以嵌套。


gle*_*man 5

反引号不嵌套。第一个嵌入的命令grep -l psycopg将在 stdin 上侦听数据,因为没有文件名。

我会说习惯使用$(this syntax)而不是反引号,因为它们可以正确嵌套。

ls -l $(grep -l psycopg $(find . -name \*py))
Run Code Online (Sandbox Code Playgroud)

  • @aking1012,你的意思是`/bin/sh` 是破折号。 (2认同)

use*_*own 5

通常以相反的方式执行,找到文件,在其中使用 grep,然后使用 find ls:

find . -name '*.py' -exec grep -q psycopg {} ";" -ls
Run Code Online (Sandbox Code Playgroud)

特殊形式的输出是可能的 (printf) 并在 find 的联机帮助页中列出。