생성 시간을 기준으로 숫자 순서를 사용하여 디렉터리의 모든 파일 이름을 바꿉니다.

생성 시간을 기준으로 숫자 순서를 사용하여 디렉터리의 모든 파일 이름을 바꿉니다.

~/folder/ contain (최신 파일부터 가장 오래된 파일까지)와 같은 디렉토리에 있는 모든 파일의 이름을 바꾸려고 합니다: apple.foo, Pie.foo, cookie.foo, melon.foo

고정 접두사와 숫자 001을 사용하여 이름을 바꿉니다.가장 오래된999로 증가합니다.

melon.foo >> object001.foo

쿠키.foo >> object002.foo

파이.foo >> object003.foo

apple.foo >> object004.foo

누구든지 이것을 달성하는 방법을 알고 있습니까?

답변1

zsh쉘 사용 :

counter=0

for name in $HOME/folder/*(.NDOm); do
    counter=$(( counter + 1 ))

    suffix=$name:e
    printf -v newname '%s/object%.3d%s' $name:h $counter ${suffix:+.$suffix}

    mv $name $newname
done

~/folder이는 마지막으로 수정된 타임스탬프를 기준으로 가장 오래된 것부터 최신 것까지 디렉터리에 있는 일반 파일의 모든 이름을 반복합니다 . 각 이름에 대해 현재 이름의 디렉터리 부분과 카운터를 사용하여 새 이름을 구성합니다. 파일 이름이 새 이름으로 변경됩니다(확인 필요 없음, 이름 충돌 확인 없음).

printf -v newname호출은 출력을 변수로 "인쇄"합니다 newname. 형식 문자열은 세 위치 (예: 등) 에 %.3d0으로 채워진 정수를 출력합니다. 001매개변수 확장은 경로 이름의 헤더/디렉토리 부분으로 확장됩니다(동일).023109$name:h$namedirname "$name"

원래 파일 이름(즉 , 현재 파일이 )으로 확장 될 $name:e"확장자" 는 에 저장됩니다 . 파일 확장자가 있으면 앞에 점을 추가합니다.fooapple.foosuffix${suffix:+.$suffix}

파일 이름 와일드카드 패턴 끝에 있는 in은 이전 와일드카드 패턴이 일반 파일에만 일치하도록 하는 와일드카드 문자입니다 .. 패턴이 마치 쉘에 설정된 것처럼 동작하도록 합니다 (.NDOm)( 일치하는 항목이 없으면 아무것도 확장하지 않고 결과에 숨겨진 이름을 포함합니다). 가장 오래된(가장 최근에 수정된) 파일이 먼저 정렬되도록 일치하는 이름을 정렬합니다.NDnullglobdotglobbashOm

로그인 셸이 아닌 경우 zsh스크립트로 실행할 수 있습니다.

$ zsh ./this-script

답변2

bash이것은 구문 분석이 필요하지 ls않고 법적으로 명명된 모든 파일(삽입 공백, 구두점, 개행 문자 등)을 처리할 수 있는 GNU 유틸리티로 작성된 버전입니다.

#!/bin/bash
k=0                                               # start at the beginning
find *.foo -type f -printf "%T@ %p\0" |           # list all the files with modification time
    sort -z |                                     # sort by increasing modification time
    cut -z -d' ' -f2- |                           # discard the time value leaving just the name
    while IFS= read -r -d '' file                 # now loop for each file...
    do
        ((++k))                                   # next count
        seq=$(printf "%03d" $k)                   # format the three-digit counter
        name="${file%.*}" ext="${file##*.}"       # split filename into name and extension
        echo will mv "$file" "$name.$seq.$ext"    # show what would happen without doing it
    done

echo willmv명령을 실행할 준비가 되면 삭제하십시오.

# preparation
for f in {melon,cookie,pie,apple}.foo; do touch "$f"; sleep 1; done

# list in order of modification time (oldest to newest)
ls -tr
melon.foo  cookie.foo  pie.foo  apple.foo

# run the script and observe the output
k=0; find *.foo -type f -printf "%T@ %p\0" | sort -z | cut -z -d' ' -f2- | while IFS= read -r -d '' file; do ((++k)); seq=$(printf "%03d" $k); name="${file%.*}" ext="${file##*.}"; echo mv "$file" "$name.$seq.$ext"; done

will mv melon.foo melon.001.foo
will mv cookie.foo cookie.002.foo
will mv pie.foo pie.003.foo
will mv apple.foo apple.004.foo

답변3

파일 이름에 공백, 탭 또는 줄 바꿈이 포함되어 있지 않다고 가정하면 한 줄 bash및 다음을 사용하는 것이 awk쉽습니다 .

ls -rt | awk -F "." '{print  $0 " object" sprintf("%03d",NR)  "." $NF }' | xargs -L 1 mv

이 명령은 각 라인에 대해 실행됩니다 xargs -l. mv명령을 실행하기 전에 다음 명령을 실행하여 대상 파일 이름과 소스 파일 이름이 올바른지 확인하십시오.

ls -rt | awk -F "." '{print  $0 " object" sprintf("%03d",NR)  "." $NF }'

출력은 다음과 유사해야 합니다.

melon.foo object001.foo
cookie.foo object002.foo
pie.foo object003.foo
apple.foo object004.foo

관련 정보