다음과 같은 디렉토리 구조가 있습니다.
.
├── event-a
│ ├── album-a
│ │ ├── a.jpg
│ │ └── x.png
│ └── album-b
│ ├── a.jpg
│ ├── x.png
│ └── y.gif
└── event-b
├── album-x
│ ├── a.jpg
│ └── x.png
└── album-y
├── a.jpg
├── x.png
└── y.gif
각 두 번째 수준 하위 폴더( album-foo
예제에서 이름 지정)에 대해 파일을 이름별로 정렬하고 확장자에 관계없이 연속 패딩 번호로 이름을 바꾸고 싶습니다. 이러한 폴더에는 JPG, PNG 또는 GIF 이미지가 포함될 수 있으며 모든 파일 확장자를 유지해야 합니다.
따라서 이 경우에는 다음과 같은 것을 얻고 싶습니다.
.
├── event-a
│ ├── album-a
│ │ ├── 01.jpg
│ │ └── 02.png
│ └── album-b
│ ├── 01.jpg
│ ├── 02.png
│ └── 03.gif
└── event-b
├── album-x
│ ├── 01.jpg
│ └── 02.png
└── album-y
├── 01.jpg
├── 02.png
└── 03.gif
rename
실용적인 사항일이 더 쉬워지면 사용하십시오.
주요 문제는 각 파일이 얼마나 얻어야 하는지 파악하는 것입니다. 중첩된 for
루프를 사용하여 반복 event-x
하고 하위 폴더를 만든 다음 각 내부 루프에 대해 직접 숫자를 추적 해야 합니까 album-x
, 아니면 제가 놓친 영리한 해결책이 있습니까?
답변1
for dir in */*; do # loop over the directories
( # run in a subshell ...
cd "$dir" # ... so we don't have to cd back
files=(*) # store the filenames in a zero-indexed array
for index in "${!files[@]}"; do
file=${files[$index]}
ext=${file##*.}
newname=$(printf "%02d.%s" $((index+1)) "$ext")
mv "$file" "$newname"
done
)
done
확장자가 없는 파일이 있다고 가정해 보겠습니다. 이 경우 선행 숫자를 제외하고 이름이 동일합니다(예: my_file
=> 05.my_file
).
디렉터리를 포함하여 숨겨지지 않은 모든 디렉터리 항목의 이름이 변경됩니다.
답변2
여기에는 두 가지 질문이 있습니다.
- 디렉토리로 재귀합니다.
- 각 개별 디렉터리에서 번호 지정 시스템을 다시 시작합니다.
이렇게 하면 두 경우 모두 원활하게 처리되지만 다른 확장도 포함하기로 결정한 경우 IMAGE_TYPES 변수를 수정해야 합니다.
#!/bin/bash
shopt -s extglob
shopt -s nocaseglob
IMAGE_TYPES='jpg|png|gif'
IFS=$'\n' dirlist=(`find "$PWD" -type d`)
for dir in "${dirlist[@]}"; do
cd "$dir"
ls *.+($IMAGE_TYPES) > /dev/null 2>&1 || continue
counter=0
for file in *.+($IMAGE_TYPES); do
printf -v newname "%.3d.%s" $((counter += 1)) "${file##*.}"
mv --verbose "$file" "$newname"
done
done
답변3
나는 동일한 트리를 만들고 모바일 빌드를 수행했습니다. 이것이 내가 생각해낸 것입니다:
n=0 IFS=.; set -f ./[e]vent*/*/*
for f do [ -n "${f##./\[*}" ] || break
[ "$d" = "${f%/*}" ] || i=0 d=${f%/*}
mv=': mv "${'$((n=$n+1))'}" "${'$n'%%/*}/'
printf "$mv%.2d%.0s.%s\"\n" $((i=$i+1)) ${f##*/}
done | sh -sx -- "$@"
마지막 파이프가 없으면 |
다음을 인쇄합니다.
mv "${1}" "${1%/*}/01.jpg"
mv "${2}" "${2%/*}/02.png"
mv "${3}" "${3%/*}/01.jpg"
mv "${4}" "${4%/*}/02.png"
mv "${5}" "${5%/*}/03.gif"
mv "${6}" "${6%/*}/01.jpg"
mv "${7}" "${7%/*}/02.png"
mv "${8}" "${8%/*}/01.jpg"
mv "${9}" "${9%/*}/02.png"
mv "${10}" "${10%/*}/03.gif"
알아요, 별 것 아닌 것 같지만 여기서 중요한 점은 이상한 파일 이름이나 다른 것에 대해 걱정할 필요가 없다는 것입니다. 이 출력의 의도된 대상은 for
루프를 공유하여 출력을 생성한 셸 입니다. 위치 배열. 내 명령에는 다음과 같은 명령이 있습니다. 다음과 같은 디버그 출력을 제공하도록 구성되어 있습니다.
+ : mv ./event-a/album-a/a.jpg ./event-a/album-a/01.jpg
+ : mv ./event-a/album-a/x.png ./event-a/album-a/02.png
+ : mv ./event-a/album-b/a.jpg ./event-a/album-b/01.jpg
+ : mv ./event-a/album-b/x.png ./event-a/album-b/02.png
+ : mv ./event-a/album-b/y.gif ./event-a/album-b/03.gif
+ : mv ./event-b/album-x/a.jpg ./event-b/album-x/01.jpg
+ : mv ./event-b/album-x/x.png ./event-b/album-x/02.png
+ : mv ./event-b/album-y/a.jpg ./event-b/album-y/01.jpg
+ : mv ./event-b/album-y/x.png ./event-b/album-y/02.png
+ : mv ./event-b/album-y/y.gif ./event-b/album-y/03.gif
:
이것이 형식 문자열의 첫 번째 문자일 때의 모습입니다 printf
. 그것을 제거하고 명령을 실행하면 다음과 같습니다.
ls ./event*/*/
./event-a/album-a/:
01.jpg 02.png
./event-a/album-b/:
01.jpg 02.png 03.gif
./event-b/album-x/:
01.jpg 02.png
./event-b/album-y/:
01.jpg 02.png 03.gif
이는 귀하의 요구 사항을 충족하는 것 같습니다. 결과를 이길 수는 없을 것 같아요.
답변4
파일 이름을 알고 있는 경우 다음을 실행하여 해당 번호를 얻을 수 있습니다.
ls -1 <your_dir> | grep <file_name> -B 1000 | wc -l