linux - 在日志文件中搜索特定文本,然后将日志文件的所有内容合并到一个文件中

标签 linux bash

我目前正在运行一个程序,该程序将药物与某些蛋白质对接并为其评分。对于一次运行,它会创建一个包含文件的唯一目录:log.txt 和 out.pdbqt(.pdbqt 文件基本上是药物的 3D 坐标)。我为数千种药物这样做,所以我在一个主目录中创建了数千个子目录。它造成了困惑。我想知道 Linux 终端或 bash 脚本在我的所有目录中的所有 log.txt 文件中搜索特定文本(文本示例为 -8.* 或 -12.* )的命令是什么我在里面。然后,任何包含该文件和特定文本的目录都会被复制到一个名为 results 的新目录中。我想要合并 .pdbqt 文件(它会弄乱 xyz 坐标)。本质上,我希望将我搜索的 log.txt 文件中包含文本的所有目录复制到一个名为 results 的目录中。

我运行的效率较低的是这个。

`#! /bin/bash

for f in drugbank/ligands_*.pdbqt; do
    b= basename $f .pdbqt
    echo Processing ligand $b
    mkdir -p $b
    ./vinaXB --config conf.txt --ligand $f --out ${b}/out.pdbqt --log ${b}/log.$
done`

这样做是为子目录/drugbank/中的所有药物运行程序 并根据药物文件的标题在程序所在的主目录中创建目录。在这种情况下配体_*.pdbqt。

然后我使用:

find . -type f -name "*.txt" -exec grep -il '-8.*' {} \;

然后我手动将给定的文件复制并粘贴到一个文件夹中,然后仔细检查它是否给出了合适的分数。

此外,如果你能给我一个 linux 命令,告诉程序打开所有子目录中具有给定名称的所有文件,那将是 peachy。假设我已经使用了 export 并更改了 ./~bashrc。

干杯!

最佳答案

如果我对你的问题的理解正确,那么只需要一小部分就可以解决你的问题:

我通过以下命令模拟了你的问题:

$ find . -name "*.cc" -exec grep -l 'main' {} \;
./autocorrelation.cc
./QATM/testQATM.cc
./QDockTreeView/testQDockTreeView.cc
./QFileDialog/testQFileDialog.cc
./QFontMetric/testQFontMetric.cc
./QGLWidgetHUD/testQGLWidgetHUD.cc
./QLabelImage/testQLabelImage.cc
./QPopup/testQPopup.cc
./QProcess/testQProcess.cc
./QRadioButtonRichText/testQRadioButtonRichText.cc
./QTableViewNoScroll/testQTableViewNoScroll.cc
./QWidgetKineticScroll/testQWidgetKineticScroll.cc
./test-bimap-mt.cc
./test-bimap.cc
./test-cout.cc
./test-dup-symbol.cc
./test-hex.cc
./test-longdouble.cc
./test-master-slave.cc
./test-op-plus.cc
./test-swap.cc
./testVecRef.cc
./testVSDebug.cc

它为每个包含特定模式的文件提供路径列表(在我的例子中是 main)。那么,如何处理这个列表呢?我将其送入 while read 循环以进行进一步处理:

$ find . -name "*.cc" -exec grep -l 'main' {} \; \
> | while read FILE; do echo cp "$FILE" ./hits/ ; done
cp ./autocorrelation.cc ./hits/
cp ./QATM/testQATM.cc ./hits/
cp ./QDockTreeView/testQDockTreeView.cc ./hits/
cp ./QFileDialog/testQFileDialog.cc ./hits/
cp ./QFontMetric/testQFontMetric.cc ./hits/
cp ./QGLWidgetHUD/testQGLWidgetHUD.cc ./hits/
cp ./QLabelImage/testQLabelImage.cc ./hits/
cp ./QPopup/testQPopup.cc ./hits/
cp ./QProcess/testQProcess.cc ./hits/
cp ./QRadioButtonRichText/testQRadioButtonRichText.cc ./hits/
cp ./QTableViewNoScroll/testQTableViewNoScroll.cc ./hits/
cp ./QWidgetKineticScroll/testQWidgetKineticScroll.cc ./hits/
cp ./test-bimap-mt.cc ./hits/
cp ./test-bimap.cc ./hits/
cp ./test-cout.cc ./hits/
cp ./test-dup-symbol.cc ./hits/
cp ./test-hex.cc ./hits/
cp ./test-longdouble.cc ./hits/
cp ./test-master-slave.cc ./hits/
cp ./test-op-plus.cc ./hits/
cp ./test-swap.cc ./hits/
cp ./testVecRef.cc ./hits/
cp ./testVSDebug.cc ./hits/

一些注意事项:

  1. 我使用 \ENTER 来格式化命令。第二行开头的 > 是 bash 的输出(通知行继续)。你可以忽略所有这些。

  2. 我实际循环的命令是 echo。如果我删除了它,循环会复制所有文件(并使我的 SSD 上的剩余可用空间更小)。我相信您将能够用适合您的情况的任何内容替换 echo cp

  3. 我在 Windows 10(64 位)、cygwin 和 bash 上执行此操作,但它应该也适用于 Linux(以及所有其他类 Unix 操作系统)。

再次阅读您的问题后,我注意到您(在标题中)要求将所有文件合并为一个文件。我在文本中以某种方式错过了它。

但是,cat 是连接cat 文件的命令。在这种情况下,cat 仅用于输出,连接是通过附加重定向 >>> 实现的,例如:

$ rm ./hits.txt ; find . -name "*.cc" -exec grep -l 'main' {} \; \
| while read FILE; do cat "$FILE" >> ./hits.txt ; done
rm: cannot remove './hits.txt': No such file or directory

$ ls -l hits.txt
-rw-rw-r--+ 1 ????? ????? 81698 Mar 18 09:19 hits.txt

注意事项:

  1. 我还做了一个 less hits.txt 来检查它是否有效。确实如此,但我不想在此处粘贴所有输出(81698 字节)。

  2. 错误消息 rm: cannot remove './hits.txt': No such file or directory 只有在 ./hits.txt 不可用时才会出现。 >> 表示“追加”。因此,在收集新结果之前删除以前的结果可能很重要。因为,我习惯于从 bashs 历史中重新调用命令行,所以重复调用变得合理。 (但是,如果 rm 以这种方式失败,它不应该有任何麻烦的副作用。)

关于linux - 在日志文件中搜索特定文本,然后将日志文件的所有内容合并到一个文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42871623/

相关文章:

php - UTF-8贯穿始终

linux - Ubuntu 中的 Terraform 路径问题

linux - 为 Linux 构建的 NSIS unicode

linux - Windows 不查看由 Linux 生成的文件

Python 忽略源 .env 文件

bash - "sh -c"不接受额外参数的问题,UNIX,使用 execve()

bash - bash 脚本(包括 SCP 和 SSH)的一个密码提示

linux - 递归查找目录中文件的数量

Phpmyadmin 可以从任何登录名和密码访问

ruby - 如何正确使用 tor-privoxy Ruby gem?