
同じ名前の形式(英数字4文字と数字)を持つファイルがたくさんありますが、その.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
名前の末尾に文字が1つしかないと判断した場合は、パターンを./*.pdb*
に変更./*.pdb?
し、内部ループのパラメータ置換に使用されるパターンをそれに応じて変更する必要があります。
.pdb*
各ファイルに対して、ファイルは削除されたサフィックスのある名前home/Desktop/chain
(${name%.pdb*}
つまり、削除されたサフィックスが一致するファイル名.pdb*
)に対応する対応するディレクトリの各ディレクトリにコピーされます。これは内部ループで行われます。
内部ループは必要cp
なぜなら、あなたがやろうとしているように、複数のターゲットディレクトリで作業することは不可能だからです。
起動時にシェルオプションを設定すると、nullglob
モードは次のように保証されます。削除済み一致するものが存在しないときに拡張しないままにする代わりに。
はい(ディレクトリビューを表示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
これはないと仮定します。文書名前の下には最後に2番目(最後に2番目)の文字がhome/Desktop/chain
あります。_
その場合は、以下を使用してください。
cd home/Desktop/chain
for dir in *_?/
do
base=${dir%_?/}
cp file/"$base".* "$dir"
done
ディレクトリのみをインポートするためにスキーマに/
追加します。*_?