我目前正在运行一个程序,该程序将药物与某些蛋白质对接并为其评分。对于一次运行,它会创建一个包含文件的唯一目录: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/
一些注意事项:
我使用
\
ENTER 来格式化命令。第二行开头的>
是 bash 的输出(通知行继续)。你可以忽略所有这些。我实际循环的命令是
echo
。如果我删除了它,循环会复制所有文件(并使我的 SSD 上的剩余可用空间更小)。我相信您将能够用适合您的情况的任何内容替换echo cp
。我在 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
注意事项:
我还做了一个
less hits.txt
来检查它是否有效。确实如此,但我不想在此处粘贴所有输出(81698 字节)。错误消息
rm: cannot remove './hits.txt': No such file or directory
只有在 ./hits.txt 不可用时才会出现。>>
表示“追加”。因此,在收集新结果之前删除以前的结果可能很重要。因为,我习惯于从 bashs 历史中重新调用命令行,所以重复调用变得合理。 (但是,如果rm
以这种方式失败,它不应该有任何麻烦的副作用。)
关于linux - 在日志文件中搜索特定文本,然后将日志文件的所有内容合并到一个文件中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42871623/