非常复杂的文件复制过程

非常复杂的文件复制过程

我面临着一个复杂的挑战。我对linux和脚本不是很实用,但我需要解决一个问题。我有一个文件 list.txt,其中包含两列,第一列是对象的名称,第二列是变量。现在我想使用此信息来复制特定目录中的特定文件。例如:

工作目录是这样的:/nfs/BioGPSDB/pockets/MD/fixed/1/

这是文件/home/tommaso/Desktop/list.txt

121p1_004_______________  GCP
13gs1_001_______________  SAS
1am42_003_______________  GNP
1bmq1_003_______________  MNO
   ecc...

在下面显示的工作目录中,有很多目录,其中一些目录的名称与文件“list.txt”第一列中存在的对象名称的前 5 个字符相关。例如:1j4r3、1t403、121p1、1sdr4、1bmq1ecc...

每个目录中都有很多文件。我需要,对于文件“list.txt”的每一行,使用第一列选择目录,进入此目录,选择感兴趣的文件并将其复制到另一个目录中(/home/tommaso/Desktop/pdb_files)。感兴趣的文件的调用方式类似于文件“list.txt”第二列中报告的变量。例子:

directory: /nfs/BioGPSDB/pockets/MD/fixed/1/121p1
File of interest: "GCP_?.pdb" where "?" is one character (letter or number)
Final directory: /home/tommaso/Desktop/pdb_files

所以最后在目录中/home/tommaso/Desktop/pdb_files我必须拥有这样的所有文件: GCP_?.pdb, SAS_?.pdb, GNP_?.pdb, MNO_?.pdb ecc..

因此,脚本应该读取该list.txt文件,并且对于第一列每行中的前 5 个字符命名的每个目录,它应该复制第二列中名为变量的文件,并将扩展名复制"_?.pdb"到所有文件都将出现的最终目录中。

我希望已经足够清楚,我希望找到愿意帮助我的人,因为我不知道从哪里开始!

答案1

您应该能够使用以下方法来做到这一点:

cd /nfs/BioGPSDB/pockets/MD/fixed/1/
while IFS= read -r line
do
  echo cp -i -- "${line:0:5}/${line##* }"_?.pdb /home/tommaso/Desktop/pdb_files/
done < /home/tommaso/Desktop/list.txt

当对打印的命令感到满意时,删除echo来实际复制文件cp

假设你只有文件${line##* }"_?.pdb与每个目录中的模式匹配,您还可以通过将命令行_?.pdb更改cp为:

cp -i -- "${line:0:5}/${line##* }"_?.pdb \
  "/home/tommaso/Desktop/pdb_files/${line##* }_?.pdb"

-i选项cp指示它在覆盖目标目录中的文件之前进行询问;根据您的要求,这不是必需的,但当来自不同目录的文件被复制/移动到单个目录时,这是有意义的。

该脚本假定每个文件名片段前面都有一个或多个空格list.txt。如果适用,请将 中的空格替换${line##* }为紧邻文件名片段之前的字符。

多种 shell(bash、ksh93、zsh、busybox ash 等)都支持这种扩展,即“替换为从索引 0(第一个字符)开始的变量${line:0:5}的五个字符子字符串”,line但不是 POSIX 的一部分,特别是在 dash 中不可用。

相关内容