폴더 구조가 복잡한 폴더가 있습니다.
├── folder1
│ ├── 0001.jpg
│ └── 0002.jpg
├── folder2
│ ├── 0001.jpg
│ └── 0002.jpg
├── folder3
│ └── folder4
│ ├── 0001.jpg
│ └── 0002.jpg
└── folder5
└── folder6
└── folder7
├── 0001.jpg
└── 0002.jpg
모든 파일이 폴더1_0001.jpg, 폴더1_0002.jpg...folder5_folder6_folder7_0001.jpg 등과 같은 고유한 이름을 가진 상위 디렉터리에 있도록 폴더 구조를 평면화하고 싶습니다.
에서 제안한 코드를 사용해 보았습니다."플랫 폴더 구조"
$ find */ -type f -exec bash -c 'file=${1#./}; echo mv "$file" "${file//\//_}"' _ '{}' \;
echo
작동 중임을 보여줍니다 .
mv folder3/folder4/000098.jpg folder3_folder4_000098.jpg
그러나 출력 파일은 상위 디렉터리에 저장되지 않습니다. 전체 드라이브를 검색했지만 출력 파일을 찾을 수 없습니다.
나도 시도했다"Bash의 파일 이름으로 플랫 폴더 구조"
$ find . -type f -name "*.jpg" | sed 'h;y/\//_/;H;g;s/\n/ /g;s/^/cp -v /' | sh
-v
작동 중임을 보여줍니다.
‘./folder3/folder4/000098.jpg’ -> ‘._folder3_folder4_000098.jpg’
그러나 출력 결과 상위 디렉터리에 숨겨진 파일이 생성되어 작업 흐름이 복잡해졌습니다. 다음을 사용하여 상위 디렉토리에서 이러한 숨겨진 파일을 볼 수 있습니다.ls -a
나는 또한 아래에 제안된 코드를 시도했다"중복 파일의 이름을 바꾸려면 Flatten Folders 명령을 사용하십시오."
find . -mindepth 2 -type f | xargs mv --backup=numbered -t . && find . -type d -empty -delete
하지만 이 명령은 비슷한 파일 이름을 가진 파일을 덮어씁니다.
비슷한 이름의 파일을 덮어쓰지 않고 복잡한 폴더 구조를 평면화하는 방법에 대한 제안 사항이 있습니까? 현재 솔루션은 한 수준 깊이의 폴더 구조에서만 작동하는 것 같습니다.
나의 궁극적인 목표는 다음에 설명된 대로 고유 이름을 연속 숫자로 변환하는 것입니다."폴더의 파일 이름을 연속된 번호로 변경"
a=1
for i in *.jpg; do
new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
mv -- "$i" "$new"
let a=a+1
done
답변1
귀하의 질문에 대한 첫 번째 해결책이 왜 작동하지 않는지 모르겠습니다. 나는 당신이 그것을 삭제하는 것을 잊었다고 가정할 수 있습니다 echo
. 여전히 실행 중이라고 가정하면 필요한 작업을 수행해야 하는 또 다른 방법이 있습니다 bash
.
shopt -s globstar
for i in **/*jpg; do mv "$i" "${i//\//_}"; done
설명하다
- 원하는 수의 디렉터리나 파일을 반복적으로 일치시키는
shopt -s globstar
bash의globstar
기능을 켭니다 .**
for i in **/*jpg;
이름이 로 끝나는 모든 파일(또는 디렉터리)을 반복하고.jpg
각 파일을$i
."${i//\//_}"
/
의 모든 인스턴스가 포함된 현재 파일(또는 디렉터리)의 이름입니다_
.
이름이 끝나는 디렉터리가 있고 .jpg
이를 건너뛰려면 대신 다음을 수행하세요.
shopt -s globstar
for i in **/*jpg; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done
확장자에 관계없이 모든 파일에 대해:
shopt -s globstar
for i in **/*; do [ -f "$i" ] && echo mv "$i" "${i//\//_}"; done
답변2
rename
Perl (때때로 Perl이라고도 함 ) 이 있는 경우 prename
다음을 수행할 수 있습니다.
find folder* -type f -name '*.jpg' -exec rename 's!/!_!g' {} \;
이는 각 파일 이름 경로를 취하고 모든 항목 /
을 _
.
파일 이름을 일련의 연속된 4자리 파일 이름으로 바꾸려면 원본 데이터 세트에서 해당 이름을 사용할 수 있습니다. 디렉터리 및 파일 이름에 일반 영숫자가 포함된 경우에만 작동합니다. 특히 공백, 쉘 구두점 또는 기타 공백이 있으면 실패합니다.
rename 's!.*!sprintf "%04d.jpg", ++$a!e' $(find folder* -type f -name '*.jpg' | sort)
rename -n ...
무엇이든 변경할 때 어떤 일이 발생하는지 확인하거나 rename -v ...
실행 시 어떤 일이 발생하는지 확인 하려면 이를 사용하세요 .
답변3
pax -rws'|/|_|g' folder*/ .
...파일 이름이 겹칠 수 없는 한 작동합니다. 이를 보다 안전하게 수행하려면 -l
링크 옵션을 사용하고 트리를 다른 경로에 미러링한 다음 이전 트리를 삭제하기 전에 새 트리를 확인하십시오.
답변4
다음 스크립트를 사용하여 성공했습니다.
#!/bin/sh
for folder in $(ls $1)
do
for file in $(ls ${folder})
do
mv ${folder}/${file} $1/${folder}_${file}
done
rmdir ${folder}
done