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
.
.
.

내가 겪고 있는 한 가지 문제는 내가 실행할 때 lsUnix가 이를 다음과 같이 나열한다는 것입니다.

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명령을 사용하여 이를 패딩 $int하고 이라는 변수에 저장합니다 padded_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

관련 정보