동일한 이름 형식(영숫자 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
이름 끝에 문자가 하나만 있다고 판단되면 패턴을 ./*.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
이는 없는 것으로 가정합니다.문서이름 아래에는 끝에서 두 번째(마지막에서 두 번째) 문자가 home/Desktop/chain
있습니다 . _
그렇다면 다음을 사용하십시오.
cd home/Desktop/chain
for dir in *_?/
do
base=${dir%_?/}
cp file/"$base".* "$dir"
done
디렉터리만 가져오기 위해 스키마 /
에 추가합니다 .*_?