查找并解决 Ubuntu 最新版本中的问题

查找并解决 Ubuntu 最新版本中的问题

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

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

find . -name '*.py'

现在,假设我只对包含字符串“psycopg”的 Python 文件感兴趣,例如因为我想从旧的 PostgreSQL 访问库过渡心理学psycopg2. 仍然足够简单:

grep -l  psycopg `find . -name '*.py'`

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

ls -l `!!`

扩展为

ls -l `grep -l  psycopg `find . -name '*.py'``

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

答案1

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

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

grep -l  psycopg $(find . -name '*.py')
ls -l $(!!)

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

答案2

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

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

ls -l $(grep -l psycopg $(find . -name \*py))

答案3

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

find . -name '*.py' -exec grep -q psycopg {} ";" -ls

可以有特殊形式的输出(printf)并在 find 的手册页中列出。

答案4

$()在或``(命令替换)中使用输出多个文件名的命令总是错误的。请参阅http://mywiki.wooledge.org/ParsingLs解释为什么你不应该这么做。

另请阅读http://mywiki.wooledge.org/UsingFindhttp://mywiki.wooledge.org/BashFAQ/020关于如何使用查找并正确处理文件名。

和不,

ls -l `grep -l  psycopg `find . -name '*.py'``

在早期版本中也不可能起作用。

用户未知的回答展示了一种完成您所询问的任务的好而安全的方法。

相关内容