
다음과 같은 이름의 많은 파일이 포함된 하위 디렉터리가 포함된 디렉터리가 있습니다.
file1.tif
file2.tif
file3.tif
file4.tif
file5.tif
file6.tif
file7.tif...
파일 이름을 얻기 위해 "cycling" 접미사 c1
및 c2
를 추가하고 싶습니다 .c3
file1c1.tif
file2c2.tif
file3c3.tif
file4c1.tif
file5c2.tif
file6c3.tif
file7c1.tif...
그리고 이것은 최상위 디렉토리의 모든 하위 디렉토리에 있습니다.
하지만 어떻게 해야 할지 모르겠습니다.
그게 가능합니까? 어떻게?
답변1
find
+ Perl 기반 prename
(일부 이전 Ubuntus라고도 함 )을 사용하면 rename
리터럴 앞의 숫자 순서를 일치시킨 .
다음 모듈로 나누기를 사용하여 원하는 형식으로 작성할 수 있습니다.
find . -name '*.tif' -execdir prename -vn -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +
( -vn
플래그를 사용하면 커밋하기 전에 파일 이름이 어떻게 바뀌는지 확인하기 위해 '모의 실행'을 수행할 수 있습니다).
전. 주어진
$ tree
.
├── bar
│ ├── file1.tif
│ ├── file2.tif
│ ├── file3.tif
│ ├── file4.tif
│ ├── file5.tif
│ ├── file6.tif
│ └── file7.tif
├── foo
│ ├── egg
│ │ ├── file1.tif
│ │ └── file2.tif
│ ├── file1.tif
│ ├── file2.tif
│ └── file3.tif
└── spam
├── file1.tif
└── file2.tif
4 directories, 14 files
그 다음에
find . -name '*.tif' -execdir prename -- 's/(\d+)\./sprintf "%dc%d.", $1, ($1-1)%3+1/e' {} +
결과
$ tree
.
├── bar
│ ├── file1c1.tif
│ ├── file2c2.tif
│ ├── file3c3.tif
│ ├── file4c1.tif
│ ├── file5c2.tif
│ ├── file6c3.tif
│ └── file7c1.tif
├── foo
│ ├── egg
│ │ ├── file1c1.tif
│ │ └── file2c2.tif
│ ├── file1c1.tif
│ ├── file2c2.tif
│ └── file3c3.tif
└── spam
├── file1c1.tif
└── file2c2.tif
4 directories, 14 files
답변2
의견을 바탕으로 편집:
즉 , 1에서 3 사이를 순환하도록 <number>
카운터 를 순환하려는 경우 :c<number>
테스트 실행:
shopt -s globstar
for d in **/*/; do
( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do
echo mv -i "$f" "${f%.tif}"c${count}.tif
if ((count=3)); then
count=1
else
((count++))
fi
done )
done
행동:
shopt -s globstar
for d in **/*/; do
( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do
mv -i "$f" "${f%.tif}"c${count}.tif
if ((count=3)); then
count=1
else
((count++))
fi
done )
done
예:
$ tree
.
├── bar
│ ├── file1.tif
│ ├── file2.tif
│ ├── file3.tif
│ └── file4.tif
├── foo
│ ├── egg
│ │ ├── file1.tif
│ │ └── file2.tif
│ ├── file1.tif
│ ├── file2.tif
│ └── file3.tif
└── spam
├── file1.tif
└── file2.tif
$ shopt -s globstar
$ for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob && for f in file*.tif; do \
echo mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
/home/foobar/bar
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
mv -i file4.tif file4c1.tif
/home/foobar/foo
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
mv -i file3.tif file3c3.tif
/home/foobar/foo/egg
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
/home/foobar/spam
mv -i file1.tif file1c1.tif
mv -i file2.tif file2c2.tif
$ for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && for f in file*.tif; do \
mv -i "$f" "${f%.tif}"c${count}.tif; if ((count=3)); then count=1; else ((count++)); fi; done ); done
$ tree
.
├── bar
│ ├── file1c1.tif
│ ├── file2c2.tif
│ ├── file3c3.tif
│ └── file4c1.tif
├── foo
│ ├── egg
│ │ ├── file1c1.tif
│ │ └── file2c2.tif
│ ├── file1c1.tif
│ ├── file2c2.tif
│ └── file3c3.tif
└── spam
├── file1c1.tif
└── file2c2.tif
원래 답변:
와 함께 bash
:
shopt -s globstar
for d in **/*/; do ( cd "$d" && pwd && count=1 && shopt -s nullglob \
&& for f in file*.tif; do echo mv -i "$f" "${f%.tif}"c${count}.tif; \
((count++)); done ); done
여기서는 디렉토리 이름을 반복하고 있습니다.
globstar
쉘 옵션을 사용하면 디렉토리를 재귀적으로 탐색할 수 있습니다.내부 부분은
()
서브셸에서 실행됩니다. 이는cd
현재 셸에서 수정되는 것을 방지하기 위한 것입니다.우리는
cd
디렉토리로 이동하여file*.tif
파일을 찾고 필요에 따라 이름을 바꿉니다.count
이름을 바꾸는 동안 각 파일에 대해 증가하는 카운터 유지
위의 내용은 시험 실행이며 이름 바꾸기가 수행될 디렉터리와 mv
실행될 명령을 보여줍니다. 만족스러우면 다음을 수행하세요.
shopt -s globstar
for d in **/*/; do ( cd "$d" && count=1 && shopt -s nullglob && \
for f in file*.tif; do mv -i "$f" "${f%.tif}"c${count}.tif; ((count++)); done ); done
쉘이 어휘 정렬을 수행하므로 파일 file10.tif
이름 이 file2.tif
. 원하지 않는 경우 이름을 바꾸기 전에 정렬을 수행하거나 옵션 zsh
과 함께 사용하십시오.numericglobsort
답변3
희마일님 덕분에 모든 일이 해결되었습니다. 우리는 표시된 주기 증가 루프를 약간 수정해야 했습니다. 왜냐하면 그것이 우리 손에서 작동하지 않았기 때문입니다. if ((count=3)) 를 다음으로 변경했습니다: if (("$count"==3)) 현재 성공적으로 사용하고 있는 최종 코드는 다음과 같습니다.
shopt -s globstar
for d in **/*/; do
( cd "$d" && count=1 && shopt -s nullglob && for f in *.tif; do
echo mv -i "$f" "${f%.tif}"c${count}.tif
if (("$count"==3)); then
count=1
else
((count++))
fi
done )
done
heemayl의 도움과 인내심에 다시 한번 감사드립니다...