我有很多名称格式相同的文件(四个字母数字字符、.pdb
和一个数字),我想将它们复制到相应的目录中。
例如,在目录中home/Desktop/chain/file
我有这些文件:
1b47.pdb1
3rty.pdb1
3rty.pdb3
7yt5.pdb1
7yt5.pdb2
7yt5.pdb5
home/Desktop/chain
现在我已经在;下创建了很多目录。目录的名称是:
1b47_A
1b47_B
3rty_H
7yt5_2
7yt5_5
7yt5_L
我想将file
目录中的文件复制到具有相同基本名称的目录中。结果是这样的:
1b47_A -> 1b47.pdb1
1b47_B -> 1b47.pdb1
3rty_H -> 3rty.pdb1 3rty.pdb3
7yt5_2 -> 7yt5.pdb1 7yt5.pdb2 7yt5.pdb5
7yt5_5 -> 7yt5.pdb1 7yt5.pdb2 7yt5.pdb5
7yt5_L -> 7yt5.pdb1 7yt5.pdb2 7yt5.pdb5
我对编程语言不是很熟悉,但我尝试使用以下代码:
cd home/Desktop/chain/file
for name in ????; do cp -r $name.pdb? home/Desktop/chain/????; done
但我得到了不同的、不想要的结果。有人可以帮我吗?
我使用脚本,并且不手动执行此操作,因为有很多文件和目录。
答案1
#!/bin/bash
shopt -s nullglob
cd home/Desktop/chain/file || exit 1
for name in ./*.pdb*; do
for dir in "../${name%.pdb*}"*/; do
cp "$name" "$dir"
done
done
这将循环遍历目录中的所有 PDB 文件home/Desktop/chain/file
,并$name
在每次迭代中保存一个名称。如果您确定.pdb
名称末尾只有一个字符,则模式./*.pdb*
应更改为./*.pdb?
,并且内循环中参数替换中使用的模式应相应更改。
.pdb*
对于每个文件,该文件都会被复制到该目录中与删除后缀的名称对应的各个目录中home/Desktop/chain
(${name%.pdb*}
即删除后缀匹配的文件名.pdb*
)。这是在内循环中完成的。
内循环是必要的因为不可能cp
像您尝试做的那样与多个目标目录一起使用。
在开始时设置nullglob
shell 选项可确保模式已删除而不是在不匹配任何内容时保留未展开状态。
示例(这显示了目录的视图chain
)
$ tree -F
.
|-- 1b47_A/
|-- 1b47_B/
|-- 3rty_H/
|-- 7yt5_2/
|-- 7yt5_5/
|-- 7yt5_L/
`-- file/
|-- 1b47.pdb1
|-- 3rty.pdb1
|-- 3rty.pdb3
|-- 7yt5.pdb1
|-- 7yt5.pdb2
`-- 7yt5.pdb5
7 directories, 6 files
循环在这里运行。结果:
$ tree -F
.
|-- 1b47_A/
| `-- 1b47.pdb1
|-- 1b47_B/
| `-- 1b47.pdb1
|-- 3rty_H/
| |-- 3rty.pdb1
| `-- 3rty.pdb3
|-- 7yt5_2/
| |-- 7yt5.pdb1
| |-- 7yt5.pdb2
| `-- 7yt5.pdb5
|-- 7yt5_5/
| |-- 7yt5.pdb1
| |-- 7yt5.pdb2
| `-- 7yt5.pdb5
|-- 7yt5_L/
| |-- 7yt5.pdb1
| |-- 7yt5.pdb2
| `-- 7yt5.pdb5
`-- file/
|-- 1b47.pdb1
|-- 3rty.pdb1
|-- 3rty.pdb3
|-- 7yt5.pdb1
|-- 7yt5.pdb2
`-- 7yt5.pdb5
7 directories, 19 files
您可以通过以下方式节省空间复制这些文件创建硬链接。您只需在脚本中更改cp
为即可完成此操作。ln
你会不是如果您打算独立于其他目录中的同名文件来修改目录中的文件,请执行此操作。硬链接只是文件的附加名称。
答案2
您可以在没有嵌套循环的情况下执行此操作:
cd home/Desktop/chain
for dir in *_?
do
base=${dir%_?}
cp file/"$base".* "$dir"
done
这假设没有文件在home/Desktop/chain
其名字下有一个 _
作为倒数第二个(倒数第二个)字符。如果有,则使用
cd home/Desktop/chain
for dir in *_?/
do
base=${dir%_?/}
cp file/"$base".* "$dir"
done
其中我们附加/
到*_?
模式以仅获取目录。