![파일 이름에 과학적 표기법으로 쓰여진 숫자 변경](https://linux55.com/image/199801/%ED%8C%8C%EC%9D%BC%20%EC%9D%B4%EB%A6%84%EC%97%90%20%EA%B3%BC%ED%95%99%EC%A0%81%20%ED%91%9C%EA%B8%B0%EB%B2%95%EC%9C%BC%EB%A1%9C%20%EC%93%B0%EC%97%AC%EC%A7%84%20%EC%88%AB%EC%9E%90%20%EB%B3%80%EA%B2%BD.png)
이미지 파일로 영상을 만들고 있는데 파일명에 과학적 표기법에 따른 숫자가 포함되어 있어서 이름 순서가 올바르지 않습니다.
파일 이름의 형식은 다음과 같습니다.
ABC_1.000000E-01.png ~ ABC_1.100000E+01.png,
DEF_1.000000E-01.png ~ DEF_1.100000E+01.png,
GHI_1.000000E-01.png ~ GHI_1.100000E+01.png,
.
.
.
숫자가 사용하는 숫자 표현을 변경하면 순서가 더 이상 맞지 않게 되므로 다음과 같이 변경하고 싶습니다.
ABC_001.png ~ ABC_110.png,
DEF_001.png ~ DEF_110.png,
GHI_001.png ~ GHI_110.png,
.
.
.
내 Linux 시스템에서 이 작업을 어떻게 수행합니까?
답변1
또한 시도
ls -1 *.png | LC_ALL=C awk -F[._] '{TMP=$2 "." $3; printf "mv %s %s_%03d.%s\n", $0, $1, 10*TMP, $4}'
mv ABC_1.000000E-01.png ABC_001.png
mv ABC_1.100000E+01.png ABC_110.png
mv DEF_1.000000E-01.png DEF_001.png
mv DEF_1.100000E+01.png DEF_110.png
mv GHI_1.000000E-01.png GHI_001.png
mv GHI_1.100000E+01.png GHI_110.png
awk
과학적 표기법으로 숫자를 분리 및 변환하고 10배 값을 제로 패딩된 정수로 출력하는 데 사용됩니다 . 예를 들어 sh
결과에 만족한다면 파이프라인을 통과해 보세요.
답변2
다음은 현재 디렉터리에서 모든 png 파일을 찾아 그에 따라 이름을 바꾸는 스크립트입니다. 기존 파일을 덮어쓰지는 않습니다.
작품 미리보기 입니다
./DEF_1.100000E+01.png - ./DEF_11.00.png
./DEF_1.000000E-01.png - ./DEF_0.10.png
./GHI_1.000000E-01.png - ./GHI_0.10.png
./ABC_1.100000E+01.png - ./ABC_11.00.png
./GHI_1.100000E+01.png - ./GHI_11.00.png
./ABC_1.000000E-01.png - ./ABC_0.10.png
스크립트 이전
$ ls
ABC_1.000000E-01.png DEF_1.000000E-01.png GHI_1.000000E-01.png script.sh
ABC_1.100000E+01.png DEF_1.100000E+01.png GHI_1.100000E+01.png
스크립트 이후
$ ls
ABC_0.10.png DEF_0.10.png GHI_0.10.png script.sh
ABC_11.00.png DEF_11.00.png GHI_11.00.png
스크립트
#!/bin/bash
for file in $(find . -type f -name "*.png")
do
number=$(echo "${file}" | cut -d'_' -f 2)
number=$(basename "${number}" .png)
number=$(echo "${number}" | awk '{ printf("%.2f\n",$1) }')
filename=$(echo "${file}" | cut -d'_' -f 1)
mv -n "${file}" "${filename}_${number}.png"
done
답변3
그리고 zsh
:
$ autoload -Uz zmv
$ zmv -n '(*_)(<->.<->E[+-]<->)(.png)' '$1${(l[3][0])$(( ($2*10)|0 ))}$3'
mv -- ABC_1.000000E-01.png ABC_001.png
mv -- ABC_1.100000E+01.png ABC_110.png
mv -- DEF_1.000000E-01.png DEF_001.png
mv -- DEF_1.100000E+01.png DEF_110.png
mv -- GHI_1.000000E-01.png GHI_001.png
mv -- GHI_1.100000E+01.png GHI_110.png
( -n
원하는 경우 시험 실행을 위해 삭제할 수 있습니다.)
perl
- 기반 변형과 유사합니다 rename
(때때로 의 (관련이 없고 더 제한적인) 명령 과 구분하기 위해 prename
or 라고도 함 ):perl-rename
rename
util-linux
$ rename -n 's{_\K\d+\.\d+E[+-]\d+(?=\.png\Z)}{sprintf "%03d", $&*10}e' ./*.png
rename(./ABC_1.000000E-01.png, ./ABC_001.png)
rename(./ABC_1.100000E+01.png, ./ABC_110.png)
rename(./DEF_1.000000E-01.png, ./DEF_001.png)
rename(./DEF_1.100000E+01.png, ./DEF_110.png)
rename(./GHI_1.000000E-01.png, ./GHI_001.png)
rename(./GHI_1.100000E+01.png, ./GHI_110.png)
둘 사이의 유사점:
- perl은
\d+
하나 이상의 십진수와 일치하는 반면, zsh는<->
임의의 십진수를 나타내는 문자열(제한되지 않은 형식<x-y>
)과 일치하므로 본질적으로 동일합니다. sprintf "%03d"
정수로 변환하고 0으로 채웁니다. zsh에서$(( number|0 ))
정수 및 패드로 변환합니다 .l[3][0]
차이점:
zmv
이름 바꾸기가 완료되기 전에 온전성 검사가 수행됩니다(예:x_1E+2.png
기존 대상 파일과의 충돌 또는 기존 대상 파일과의 충돌).x_10E+1.png
- zsh의
l
매개변수 확장 플래그는 패딩되지만 지정된 너비로 잘립니다. 따라서 (1200)은 으로1.2E+3
잘려서 로 남습니다 .200
sprintf "%03d"
1200