약 천 개의 파일이 있는데 모두 다음과 같습니다.
20091208170014.nc
20091211150704.nc
20091214131328.nc
20091217111953.nc
20091220092643.nc
20091223073308.nc
20091226053932.nc
20091229034557.nc
20091208171946.nc
20091211152610.nc
처음 8자리는 날짜이고 마지막 6자리는 연속된 숫자이지만 이 숫자의 차이는 파일마다 동일하지 않습니다. 나는 마지막 6개의 숫자가 연속적이고 항상 동일한 단계를 갖기를 원합니다. 예를 들어:
20091208000001.nc
20091211000002.nc
20091214000003.nc
20091217000004.nc
20091220000005.nc
20091223000006.nc
20091226000007.nc
20091229000008.nc
20091208000009.nc
20091211000010.nc
mmv
비슷한 방법을 사용하여 이 사이트에서 몇 가지 질문을 확인했습니다.https://www.ostechnix.com/how-to-rename-multiple-files-at-once-in-linux/하지만 그들 중 누구도 내 이름에 연속된 숫자를 포함하는 방법을 설명하지 못했습니다.
문제와 구별하기 위해파일 이름을 연속된 숫자로 일괄 변경, 순차적 순서는 마지막 6자리를 기준으로 해야 하며 처음 8자리에 포함된 날짜는 완전히 무시됩니다.
답변1
perl
기반 rename
도구(때때로 호출됨)가 설치되어 있는 경우 prename
다음과 같이 한 줄로 이 작업을 수행할 수 있습니다.
rename -n 's/^(.{8})(.{6})\.(.*)/sprintf "%s%06d.%s", $1, ++$a, $3/e' *.nc
작성된 대로, 이는 수행할 작업만 알려줍니다. 만족스러우면 -n
자동 실행을 제거하거나 교체하고 -v
무슨 일이 일어나는지 확인하세요.
궁금하신 분은 세 (..)
부분(여기서는 문자를 나타내고 .{n}
,n
.*
아무것, 괄호는 형식화된 인쇄 결과에 첫 번째 그룹과 증가하는 6자리 숫자가 포함되는 그룹을 만듭니다. (두 번째 그룹은 사용되지 않습니다.) 세 번째 그룹에는 파일 확장자가 포함됩니다.
기존 파일 덮어쓰기를 거부한다는 점을 지적하고 싶습니다.
샘플 출력
20091208170014.nc renamed as 20091208000001.nc
20091208171946.nc renamed as 20091208000002.nc
20091211150704.nc renamed as 20091211000003.nc
20091211152610.nc renamed as 20091211000004.nc
20091214131328.nc renamed as 20091214000005.nc
20091217111953.nc renamed as 20091217000006.nc
20091220092643.nc renamed as 20091220000007.nc
20091223073308.nc renamed as 20091223000008.nc
20091226053932.nc renamed as 20091226000009.nc
20091229034557.nc renamed as 20091229000010.nc
포함된 날짜를 완전히 무시하고 파일 이름의 마지막 6자리를 기준으로 정렬하려는 것 같습니다. 여기에는 몇 가지 옵션이 있습니다.
쉘이 목록을 완전히 확장할 수 있을 만큼 파일 수가 작은 경우 파일은 다음과 같이 정렬됩니다.
rename -n '..as above..' $(ls -d *.nc | sort -k1.9,1.14n)
정렬 키가 일시적으로 파일 이름 앞에 배치된 다음 이름이 바뀌고 해당 키가 속한 위치가 바뀌도록 변환을 수행합니다.
# Swap the first eight and second six groups around rename -n 's/^(.{8})(.{6})\.(.*)/$2$1.$3/' *.nc # Apply the transform with the shell sorting by original sequence rename -n 's/^(.{6})(.{8})\.(.*)/sprintf "%06d%s.%s", ++$a, $2, $3/e' *.nc # Swap back the first six and second eight groups rename -n 's/^(.{6})(.{8})\.(.*)/$2$1.$3/' *.nc
이전과 마찬가지로 제거 -n
하여 자동으로 실행하거나 교체하여 -v
실제로 어떤 일이 발생하는지 확인하세요.
답변2
Bash에서는 충돌 검사 없이:
index=1
for file in [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].nc
do
mv -- "$file" "${file:0:8}"$(printf "%06d" "$index").nc
((++index))
done
와일드카드 [0-9]...
선택에는 8+6(14) 자리 숫자와 가 포함됩니다 .nc
. 이는 이러한 모든 파일을 반복하여 이름을 바꿉니다. 대상 파일 이름은 다음 세 부분으로 생성됩니다.
"${file:0:8}"
-- 기존 파일명(날짜)의 처음 8글자$(printf "%06d" "$index")
-- 6비트 제로 패딩 인덱스.nc
-- 기존 확장
예제 파일에서 위 루프의 "echo" 버전을 실행하면 다음과 같은 결과를 얻습니다.
mv -- 20091208170014.nc 20091208000001.nc
mv -- 20091208171946.nc 20091208000002.nc
mv -- 20091211150704.nc 20091211000003.nc
mv -- 20091211152610.nc 20091211000004.nc
mv -- 20091214131328.nc 20091214000005.nc
mv -- 20091217111953.nc 20091217000006.nc
mv -- 20091220092643.nc 20091220000007.nc
mv -- 20091223073308.nc 20091223000008.nc
mv -- 20091226053932.nc 20091226000009.nc
mv -- 20091229034557.nc 20091229000010.nc