我的层次结构是 MyPDB -(5rea,5res,5rez),其中每个5rea
, 5res
, .. 包含一个名为 的目录MD
,其中包含一个名为production_10ns.out
.我想从 等 下的每个子目录复制到production_10ns.out
每个MD
等下已经存在的另一个子目录。请让我知道哪里出了问题。 5rea
5res
analysis
5rea
5res
我努力了
$ for production_10ns.out in /scratch/srnaik/MyPDB/*/MD
do cp production_10ns.out /scratch/srnaik/MyPDB/*/analysis/
done
答案1
我相信这就是您正在寻找的层次结构
scratch/
└── srnaik
└── MyPDB
├── 5rea
│ ├── MD
│ │ └── production_10ns.out
│ └── analysis
│ └── production_10ns.out
├── 5res
│ ├── MD
│ │ └── production_10ns.out
│ └── analysis
│ └── production_10ns.out
└── 5rez
├── MD
│ └── production_10ns.out
└── analysis
└── production_10ns.out
如果是这样,这个脚本就可以解决问题,
#!/bin/bash
cd /scratch/srnaik/MyPDB
for i in {a..z}; do
[ -d "5re${i}" ] && cp 5re${i}/MD/production_10ns.out 5re${i}/analysis/
done
答案2
您的代码中有两个问题:
- 变量通常不能包含点(在循环
production_10ns.out
中用作变量名for
)。 - 您无法使用 一次将文件复制到多个目录
cp
,您似乎是通过使用通配模式作为目标路径来完成此操作。
相反,循环所有production_10ns.out
文件并将它们复制到新位置:
for pathname in /scratch/srnaik/MyPDB/*/MD/production_10ns.out; do
cp "$pathname" "${pathname%/*}/../analysis"
done
这里,"$pathname"
将是production_10ns.out
每次迭代中文件的绝对路径名。
扩展${pathname%/*}
将删除路径名末尾的实际文件名,因此 if $pathname
is /scratch/srnaik/MyPDB/5rea/MD/production_10ns.out
,则将${pathname%/*}
扩展为/scratch/srnaik/MyPDB/5rea/MD
.
您还可以使用$( dirname "$pathname" )
代替${pathname%/*}
:
for pathname in /scratch/srnaik/MyPDB/*/MD/production_10ns.out; do
cp "$pathname" "$( dirname "$pathname" )/../analysis"
done
../analysis
目标路径末尾的会找到同级analysis
目录。
假设该目录存在,该cp
命令会将文件复制到其中。
到确保目标目录存在,使用
mypdb_dir=/scratch/srnaik/MyPDB
for pathname in "$mypdb_dir"/*/MD/production_10ns.out; do
[ ! -f "$pathname" ] && continue
targetdir=$( dirname "$pathname" )/../analysis
mkdir -p "$targetdir" || exit 1
cp "$pathname" "$targetdir"
done
如果目标目录尚不存在,这将创建目标目录,否则将退出未能创建目录的 shell。
我还明确测试我们当前正在调查的文件是否确实存在并且首先是常规文件(通过测试-f
)。如果我们迭代的模式不匹配任何文件,它将保持未展开状态,并且测试捕获了这种情况。
添加的额外变量mypdb_dir
只是为了使代码更整洁一些。