Unix가 번호순으로 나열하도록 파일 이름을 채웁니다.

Unix가 번호순으로 나열하도록 파일 이름을 채웁니다.

다음 형식의 여러 파일이 포함된 폴더가 있습니다.

C Block Scan copy 1.pdf
C Block Scan copy 2.pdf
C Block Scan copy 3.pdf
C Block Scan copy 4.pdf
.
.
.

ls내가 가진 한 가지 문제는 Unix를 실행할 때 그것들을 다음과 같이 나열한다는 것입니다.

C Block Scan copy 1.pdf
C Block Scan copy 10.pdf
C Block Scan copy 11.pdf
C Block Scan copy 12.pdf
.
.
.

Unix가 (희망적으로) 순서대로 나열할 수 있도록 숫자를 채우고 싶습니다.

C Block Scan copy 01.pdf
C Block Scan copy 02.pdf
C Block Scan copy 03.pdf
.
.
.
C Block Scan copy 09.pdf
C Block Scan copy 10.pdf
C Block Scan copy 11.pdf
C Block Scan copy 12.pdf
.
.
.

비슷한 문제가 있는 게시물을 찾았습니다파일 이름의 숫자를 고정 길이로 패드, 그러나 내 상황에 그들의 솔루션을 적용하려고 시도했지만 제대로 작동하지 못했습니다. 내가 시도한 것은 다음과 같습니다.

for f in *.pdf; do
    int=`basename $f .pdf | cut -d '.' -f 2`
    new_name=`printf "file.%0.2i.pdf\n” $int`
    [ ! -f $new_name ] && mv $f $new_name
done

나는 이것이 내 상황에 대한 그들의 솔루션을 맹목적으로 적용한 것임을 인정합니다. 나는 기본 구문을 실제로 이해하지 못하고 StackExchange에서 게시물에 댓글을 달 만큼 높은 순위를 차지하지 않기 때문에 마음에 들지 않습니다.

저는 쉘 스크립팅을 처음 접했기 때문에 구문의 의미에 대한 설명이 도움이 될 것입니다.

도움이 된다면 macOS Mojave 10.14.6을 사용하고 있으며 Brew가 설치되어 있습니다.

미리 감사드립니다.

답변1

사용 zsh(현재 macOS의 기본 사용자 셸):

autoload zmv # best in ~/.zshrc
zmv '(* )([0-9].pdf)' '${1}0$2'

답변2

그러면 현재 디렉터리에서 이름이 질문에 설명된 패턴을 따르는 모든 "*.pdf" 파일을 찾아 동일한 이름으로 이름을 바꾸지만 숫자는 2자리로 채워집니다.

#!/usr/bin/env bash

shopt -s nullglob

for f in *[[:space:]][0-9].pdf; do
    int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1)"
    name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"
    padded_int="$(printf "%02d\n" "$int")"

    echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"

done

실제로 실행하기 전에 제거하세요 echo. 하지만 원하는 대로 작동하는지 확인하려면 먼저 있는 그대로 실행하세요. 위 스크립트를 다음 위치에 저장하는 사용 예:mvmvpdf.sh

$ for i in {1..10}; do touch "C Block Scan copy $i.pdf"; done
$ ./pdf.sh
mv C Block Scan copy 1.pdf C Block Scan copy 01.pdf
mv C Block Scan copy 2.pdf C Block Scan copy 02.pdf
mv C Block Scan copy 3.pdf C Block Scan copy 03.pdf
mv C Block Scan copy 4.pdf C Block Scan copy 04.pdf
mv C Block Scan copy 5.pdf C Block Scan copy 05.pdf
mv C Block Scan copy 6.pdf C Block Scan copy 06.pdf
mv C Block Scan copy 7.pdf C Block Scan copy 07.pdf
mv C Block Scan copy 8.pdf C Block Scan copy 08.pdf
mv C Block Scan copy 9.pdf C Block Scan copy 09.pdf

첫번째 줄:

#!/usr/bin/env bash

셰르본. 또한 env나는그 특성.

이 줄

shopt -s nullglob

세트빈 공 주택 옵션 이는 링크된 웹사이트에도 설명되어 있습니다:

nullglob

If set, Bash allows filename patterns which match no files to
expand to a null string, rather than themselves.

패턴 조건과 일치하는 파일이 없으면 for 루프가 시작되지 않도록 해야 합니다.

for f in *[[:space:]][0-9].pdf; do

*[[:space:]][0-9].pdf이름이 임의 개수의 문자, 공백, 숫자, 다음으로 끝나는 파일을 찾는 것을 의미하는 셸 모드입니다..pdf. 루프 내부에는 $f처리된 .pdf 파일의 이름이 저장됩니다.

여기

int="$(basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1)"

우리는 사용명령 대체 주어진 파일 이름의 정수 부분을 변수에 할당합니다. 터미널에서 파이프라인의 내용을 basename보고 재현 할 수 있습니다 .man basename

$ f='C Block Scan copy 1.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1
1
$ f='C Block Scan copy 5.pdf'
$ echo basename "$f" | rev | cut -d ' ' -f1 | rev | cut -d . -f1
5

(참고 $명령줄 프롬프트 명령의 일부가 아닌 새 줄의 시작을 나타내는 데 사용됩니다.

다음 줄에

name="$(basename "$f" | rev | cut -d ' ' -f2- | rev)"

.pdf에서 숫자 앞의 모든 이름 부분을 추출합니다.

다음 줄에

padded_int="$(printf "%02d\n" "$int")"

Bash 내장 명령을 사용하여 이를 변수로 printf채우고 저장합니다 . 루프의 마지막 줄에$intpadded_int

echo mv "$f" "$(printf "%s %s.pdf" "$name" "$padded_int")"

echo물론 명령 대체를 사용하여 실제 이름 바꾸기를 다시 실행합니다 printf . C에서처럼 printf2개의 형식 지정자와 2개의 해당 인수와 함께 사용됩니다.%s

마지막 줄

done

루프를 닫습니다.

답변3

PE 매개변수 확장을 사용합니다. mv셸의 외부 도구 에만 적용됩니다 bash.

#!/usr/bin/env bash

shopt -s nullglob

for f in *[[:space:]][0-9].pdf; do
  n=${f##* }  ##: Remain only 1.pdf, 2.pdf etc.
  n=0${n%.*}  ##: Remain only 1 , 2 etc. and pad 0 so it will be 01, 02 ..
  echo mv -v "$f" "${f/[0-9]/"$n"}"  ##: Replace all [0-9] with the value of "$n"
done

관련 정보