遍历文件以查找字符串并将包含该字符串的文件发送到 bash 中的同名目录
Loop through files to find a string and send files containing that string to directories of the same name in bash
我有一个包含约 500 个文件的父目录,每个文件名都以 cert
开头,即 cert-104.mol2
、cert-105.mol2
等等。这些 cert
个文件中的每一个都包含一个七位数的标识符,即 7988114
。大约有 20 个唯一的七位数字标识符。我创建了一个目录 (unique_ligands
),其中包含每个唯一标识符的目录,即名为 7988114
的目录。在每个目录中都有一个 .mol2
文件,其中包含标识符的名称,即 7988114.mol2
。总而言之,文件结构如下所示:
/parent/unique_ligands/7988114/7988114.mol2
其中 7988114 是 ~20 个唯一标识符之一。
在父目录~500个文件中,我需要遍历每个cert文件,挑出唯一的七位标识符,并将其发送到相应的identifier.mol2
文件。作为初学者 bash 脚本编写者,我不确定如何处理这个问题。我编写了针对单个标识符执行此过程的代码,7988114
:
find . -type f -name 'cert*' -exec grep -q '7988114' {} ';' -exec cp {} ./unique_ligands/7988114 ';'
cd unique_ligands/7988114
bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
mv zzz.txt 7988114.mol2
rm null
rm cert*
我怎样才能把它变成一个能够挑选出任何七位数字标识符的循环?或者有更好的方法来解决这个问题吗?
编辑
为了阐明上面示例代码中每一行的作用:
find ...
此行搜索所有以文件名 cert
开头的 ~500 个文件,并挑选出内容包含字符串 7988114
的文件并将它们复制到正确的位置7988114
目录。每个 cert
文件包含约 100 行分子坐标、电荷信息等。
bash -c ...
此行循环遍历复制到 7988114
目录中的每个 cert
文件,并将文件内容添加到新的文本文件 zzz.txt
。每个 cert
文件的名称类似于 cert-1.mol2
、cert-2.mol2
等。对我来说至关重要的是,此行搜索每个 cert
文件,从 1 一直到上限 10,000,然后按顺序将它们添加到 zzz.txt
。我发现的其他示例要么没有按顺序搜索,要么在浏览 cert-2*
文件之前浏览了 cert-1*
文件。
mv zzz.txt 7988114.mol2
由于某些原因,我不允许在上面创建 7988114.mol2
文件,所以我在这里创建了
这是我想出如何回答上面我自己的问题的一种方法(在上面用户 shellter 的帮助和启发下 - 谢谢!):
ls -l | grep ^d | awk '{print }' > list_of_ligands.txt
mv list_of_ligands.txt ..
cd ..
while read NAME
do
echo "$NAME"
grep -l "$NAME" cert* | while read -r filename ; do
cp $filename unique_ligands/$NAME
cd unique_ligands/$NAME
bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
mv zzz.txt $NAME.mol2
rm null
rm cert*
cd ../..
done
done < list_of_ligands.txt
正如我在最初的问题中提到的,我之前已经为每个 7 号标识符创建了一个目录。 ls -l
行选择目录名称并创建目录名称的垂直列表(同样,这只是我拥有的每个 7 数字标识符)。
这两个 while
循环遍历我拥有的每个 7 数字标识符,并执行我在最初的问题中提到的命令。
我有一个包含约 500 个文件的父目录,每个文件名都以 cert
开头,即 cert-104.mol2
、cert-105.mol2
等等。这些 cert
个文件中的每一个都包含一个七位数的标识符,即 7988114
。大约有 20 个唯一的七位数字标识符。我创建了一个目录 (unique_ligands
),其中包含每个唯一标识符的目录,即名为 7988114
的目录。在每个目录中都有一个 .mol2
文件,其中包含标识符的名称,即 7988114.mol2
。总而言之,文件结构如下所示:
/parent/unique_ligands/7988114/7988114.mol2
其中 7988114 是 ~20 个唯一标识符之一。
在父目录~500个文件中,我需要遍历每个cert文件,挑出唯一的七位标识符,并将其发送到相应的identifier.mol2
文件。作为初学者 bash 脚本编写者,我不确定如何处理这个问题。我编写了针对单个标识符执行此过程的代码,7988114
:
find . -type f -name 'cert*' -exec grep -q '7988114' {} ';' -exec cp {} ./unique_ligands/7988114 ';'
cd unique_ligands/7988114
bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
mv zzz.txt 7988114.mol2
rm null
rm cert*
我怎样才能把它变成一个能够挑选出任何七位数字标识符的循环?或者有更好的方法来解决这个问题吗?
编辑
为了阐明上面示例代码中每一行的作用:
find ...
此行搜索所有以文件名 cert
开头的 ~500 个文件,并挑选出内容包含字符串 7988114
的文件并将它们复制到正确的位置7988114
目录。每个 cert
文件包含约 100 行分子坐标、电荷信息等。
bash -c ...
此行循环遍历复制到 7988114
目录中的每个 cert
文件,并将文件内容添加到新的文本文件 zzz.txt
。每个 cert
文件的名称类似于 cert-1.mol2
、cert-2.mol2
等。对我来说至关重要的是,此行搜索每个 cert
文件,从 1 一直到上限 10,000,然后按顺序将它们添加到 zzz.txt
。我发现的其他示例要么没有按顺序搜索,要么在浏览 cert-2*
文件之前浏览了 cert-1*
文件。
mv zzz.txt 7988114.mol2
由于某些原因,我不允许在上面创建 7988114.mol2
文件,所以我在这里创建了
这是我想出如何回答上面我自己的问题的一种方法(在上面用户 shellter 的帮助和启发下 - 谢谢!):
ls -l | grep ^d | awk '{print }' > list_of_ligands.txt
mv list_of_ligands.txt ..
cd ..
while read NAME
do
echo "$NAME"
grep -l "$NAME" cert* | while read -r filename ; do
cp $filename unique_ligands/$NAME
cd unique_ligands/$NAME
bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
mv zzz.txt $NAME.mol2
rm null
rm cert*
cd ../..
done
done < list_of_ligands.txt
正如我在最初的问题中提到的,我之前已经为每个 7 号标识符创建了一个目录。 ls -l
行选择目录名称并创建目录名称的垂直列表(同样,这只是我拥有的每个 7 数字标识符)。
这两个 while
循环遍历我拥有的每个 7 数字标识符,并执行我在最初的问题中提到的命令。