파일 이름의 숫자를 줄이기 위해 여러 파일의 이름을 바꾸시겠습니까?

파일 이름의 숫자를 줄이기 위해 여러 파일의 이름을 바꾸시겠습니까?

내 파일 이름이 잘못 지정되었지만 -1이 동기화되지 않았습니다. 문제는 수천 개의 이름을 바꿔야 한다는 것입니다.

  • DBGC180_805754
  • DBGC180_805755
  • DBGC180_805756

도착하다

  • DBGC180_805753
  • DBGC180_805754
  • DBGC180_805755

나는 bash 스크립트나 unix 명령을 사용하는 것을 선호합니다.

답변1

다음을 수행할 수 있습니다.

# {smallestfilenum..largestfilenum}

for i in {805754..999999}; do 
   mv "DBGC180_$i" "DBGC180_$(($i-1))";
done

더 작은 숫자(예: 805754..805758)로 시도하여 예상대로 작동하는지 확인하세요. 새 이름의 파일이 이미 존재하는 경우 해당 파일을 덮어쓰게 되므로 주의하세요.

답변2

  1. 이름을 바꿀 파일을 하위 디렉터리로 이동합니다(이름을 변경하지 않고).
  2. 하위 디렉터리의 파일 이름을 원래 디렉터리로 바꿉니다.

1단계가 없어도 가능하지만 두 가지 이유로 1단계를 권장합니다.

  • 명령이 중단되면 어떤 파일의 이름이 변경되었고 어떤 파일이 변경되지 않았는지 분명해지기 때문에 중단한 부분부터 계속할 수 있습니다.
  • 잘못된 순서로 이름을 바꾸거나 기존 파일 중 하나를 덮어쓰는 것에 대해 걱정할 필요가 없습니다.

테스트되지 않은 쉘 조각(감소되는 숫자에 앞에 0이 붙지 않는다는 사실에 의존함):

mkdir to_decrement
for x in DBGC180_80575[4-9] DBGC180_8057[6-9]? DBGC180_805[8-9]?? DBGC180_80[6-9]??? DBGC180_8[1-9]???? DBGC180_9?????; do
  mv "$x" to_decrement/
done
cd to_decrement
for x in *; do
  number="${x##*_}"
  mv -i -- "$x" "../${x%_*}_$((number-1))"
done
cd ..
rmdir to_decrement

그리고다루기 힘든, 덕분에 이 작업을 더욱 쉽게 할 수 있습니다.번호 범위 글로벌, 그것은내장mv이렇게 하면 명령줄 길이 제한이 발생하는 것을 방지할 수 있습니다.패턴 기반 일괄 이름 변경 기능. zsh에서:

autoload -U zmv
zmodload -m -F zsh/files b:zf_\*
mkdir to_decrement
zf_mv DBGC180_<805754-> to_decrement/
zmv 'to_decrement/(*)_(*)' '${1}_$(($2-1))'
rmdir to_decrement

답변3

그래서 이름을 , to 등 DBGC180_805754으로 바꾸고 싶습니다 . 이것이 제가 해결하고 싶은 문제입니다.DBGC180_805753...55...54

먼저 이 스크립트를 현재 위치 어딘가에 배치 PATH하고 이름을 waltinator.

#!/bin/bash
#step through the parameters 
while [[ -n "$1" ]] ; do
    oldname="$1"
    # shift the arguments left
    shift;
    # strip off the fixed part of the old name
    oldnum=${oldname##DBGC180_}
    # decrement the number (this is what was wanted, right?)
    newnum=$(( $oldnum - 1 ))
    # build the new, improved filename
    newname="DBGC180_$newnum"
    if [[ -f "$newname" ]] ; then
        printf "Cannot rename $oldname to $newname, $newname exists.\n" >&2
        exit 1
    fi
    mv --no-clobber "$oldname" "$newname"
done
exit 0

다음 단계에서는 스크립트가 에 있고 $HOME/bin/waltinator가 있다고 가정합니다 chmod +x $HOME/bin/waltinator.

find . -type f -name 'BDGC180_[0-9][0-9][0-9][0-9][0-9][0-9]` -print | \
    sort | \
    xargs $HOME/bin/waltinator

이름 이 쉘 glob 패턴 " 뒤에 6자리 숫자( )와 일치하는 find파일을 (특정 순서 없이) 찾습니다 . 정렬된 목록이 필요하므로(이전에 이름을 바꾸면 실패함) through의 출력을 실행합니다. 그런 다음, 인수 목록을 줄여야 하는 경우 (정렬된) 파일 이름 목록을 얻고 (정렬된) 파일 이름 목록을 읽기에 전달하는 명령을 작성합니다.BDGC180_[0-9]...97...96...96findsortxargs$HOME/bin/waltinatorman xargs

이렇게 하려면 다음 내용을 읽어 보십시오.

for page in bash mv find sort xargs ; do
    man "$page"
done   

답변4

rename각 숫자를 1을 뺀 숫자로 바꾸는 데 사용됩니다 .

$ rename -v 's/\d{6}/sprintf("%06",($&-1))/e'    

노트

  • renamePerl 표현식을 사용하여 파일 이름을 바꿉니다.
  • srename정규식 패턴의 일부 또는 전부와 일치하는 파일 이름이 바뀌도록 지정합니다 .
  • Perl 대체 표현식의 구조는 다음과 같습니다.
    • s/PATTERN/REPLACEMENT/MODIFIER
  • \d{6}rename검색되어 교체될 패턴입니다. 소수점 6자리입니다.
  • $일치하는 하위 문자열을 저장하는 변수입니다 \d{6}(이 경우 "substring"은 int입니다).
  • sprintf("%06",($&-1))에 저장된 값을 검색하여 $감소시키고 해당 값을 대체 값으로 반환합니다. 선행 0을 처리하는 데 사용 됩니다 %06.
  • erename대체 항목이 Perl 문으로 평가되고 해당 반환 값이 대체 텍스트로 사용되도록 지정합니다 .
  • -vrenameecho가 수행하는 작업을 수행 하도록 합니다 .

더욱 안전해지려면 이 플래그를 사용하여 수행할 작업만 알려주고 실행하지 않도록 하십시오 -n.rename

이는 감소에만 작동하는 것으로 보이므로 주의해서 처리하십시오.

관련 정보