9

我正在使用 find 来查找为查询返回一些行的数据库的名称。

$ find . -name 'sqlite.db' -exec sqlite3 "{}" 'SELECT * FROM table WHERE column1="value"' \; 

value|a|b|c|d

但我想要数据库的名称,所以我尝试了显示所有名称的 -print

$ find . -name 'sqlite.db' -print -exec sqlite3 "{}" 'SELECT * FROM table WHERE column1="value"' \; 

/dir1/a/sqlite.db
value|a|b|c|d
/dir2/a/sqlite.db
/dir2/b/sqlite.db
/dir3/a/sqlite.db

有没有办法只获取命令运行的退出状态为成功的文件。

4

3 回答 3

11

你只需要-print-exec. 这是一个短路 boolean and,并且通过放置-printbefore -exec,打印发生在 exec 之前。

find . -name sqlite.db -exec ... \; -print
于 2013-01-30T18:57:38.767 回答
1

即使没有找到符合条件的数据, sqite3 也会返回 0。仅当 sql 语句本身或传递的参数中存在错误时,它才返回 false。

sqlite3 sqlite.db 'SELECT * FROM table WHERE column1="value"'

即使数据库中没有匹配列,也会返回 0。您可以将命令与 grep 结合使用以使查找工作。

sqlite3 sqlite.db 'SELECT * FROM table WHERE column1="value" | grep value

所以你的 find 命令变成

find . -name 'sqlite.db' -exec sqlite3 "{}" 'SELECT * FROM table WHERE column1="value"' | grep value \;

编辑:

以上不起作用,因为 exec 无法处理管道。请参阅如何包含管道 | 在我的 linux 中找到 -exec 命令?

find . -name "*.db" -type f | while read file ; do sqlite3 $file "SELECT * FROM table WHERE column1='value'" | grep value ; if [ $? -eq 0 ] ; then echo $file ; fi done

我已经对此进行了测试并且可以正常工作,但我不确定这是否是您正在寻找的解决方案。

于 2013-01-30T07:31:20.313 回答
0

您可以获取退出状态并在 if 语句中对其进行测试,以便执行您想要的操作。

获得此状态的方法是使用$?变量。这是一个关于它的教程:http: //tldp.org/LDP/abs/html/exit-status.html

如果您想在find命令之后添加更多代码,您可以查看为xargs找到的每个输出行执行一个 shell 脚本,find使用以下命令将结果作为参数传递xargs

find . -name 'sqlite.db' | xargs <your_script>.sh

此外,在您的情况下,另一种解决方案可能是使用AWK对每个find输出行执行查询并分别分析其结果:

find . -name 'sqlite.db' | awk '{system("sqlite3 ..."); if () {} else {} }' -
于 2013-01-30T07:31:09.913 回答