참가자를 나타내는 폴더가 여러 개 있습니다. 각 폴더에는con_0001.img. 이 모든 파일을 이동하고 싶습니다(con_0001.img)을 새 폴더로 복사합니다(개별 참가자 폴더에 배치하는 대신).
아래 코드는 다음을 찾는 것 같습니다.con_0001.img라는 새 폴더로 이동하십시오.SA_A:
find . -name "con_0001.img" -exec mv '{}' "./SA_A/" ";"
그러나 모든 파일의 이름이 이므로 con_0001.img
새 폴더에는 단 하나의 파일만 남게 됩니다(아마도 이후의 모든 파일이 서로 덮어쓰기 때문일 것입니다).
나는 이 재정의를 방지하기 위한 제안을 찾았습니다. 즉:
find . -name "con_0001.img" -exec mv --backup=numbered "{}" "./SA_A/" \;
그러나 결국 파일이 생겼습니다.con_0001.img여러 폴더에서 사라져서 덮어쓴 것 같습니다. mv
로 변경하면 cp
파일도 생성됩니다(그러나 파일을 복사하여 예상한 대로 파일은 그대로 유지됩니다).
덮어쓰기를 방지할 수 있는 방법이 있나요? 더 이상적으로는 파일을 새 폴더로 이동할 때 상위 디렉터리 이름(참가자 번호)의 일부를 파일에 추가할 수 있는 방법이 있습니까? 예를 들어:
p102/con_0001.img ----> p102_con_0001.img
p105/con_0001.img ----> p105_con_0001.img
이동된 파일에 상위 디렉터리를 추가해야 하는 것처럼 다음 코드를 적용해 보았습니다.
find . -name 'con_0001.img' | while read filePath; do cp "$filePath" './SA_A'/"$(echo "$filePath")"; done
그러나 오류가 반환됩니다.
일반 파일 '/SA_A/./p105/con_0001.img'을 생성할 수 없습니다. 해당 파일이나 디렉터리가 없습니다.
새 폴더 이후 예상치 못한 기간이 있는 것 같습니다./SA_A/.이것이 코드가 작동하지 않는 이유일까요? 이 기간은 어디에서 왔습니까?
답변1
mkdir SA_A
find . -name "con_0001.img" -exec sh -c '
for f; do d=${f%/*}; mv -- "$f" "./SA_A/${d#./}${f##*/}"; done
' findsh {} +
for 루프는 발견된 각 파일을 반복합니다.
d=${f%/*}
파일의 기본 이름인 가장 오른쪽/*
부분을 제거합니다.f
${d#./}
./
파일의 앞 부분을 제거합니다.${f##*/}
파일의 기본 이름을 가져오고 마지막 파일을 제거합니다/
.
실행 전:
$ ls a1 a2 a3
a1:
con_0001.img
a2:
con_0001.img
a3:
con_0001.img
실행 후:
$ ls a1 a2 a3 SA_A/
a1:
a2:
a3:
SA_A/:
a1con_0001.img a2con_0001.img a3con_0001.img
그러나 단일 쉘 루프를 사용하면 훨씬 더 간단합니다.
for f in */con_0001.img; do
mv -- "$f" "./SA_A/${f%/*}_${f#*/}"
done