내 파일 이름이 잘못 지정되었지만 -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단계가 없어도 가능하지만 두 가지 이유로 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
...96
find
sort
xargs
$HOME/bin/waltinator
man 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'
노트
rename
Perl 표현식을 사용하여 파일 이름을 바꿉니다.s
rename
정규식 패턴의 일부 또는 전부와 일치하는 파일 이름이 바뀌도록 지정합니다 .- Perl 대체 표현식의 구조는 다음과 같습니다.
s/PATTERN/REPLACEMENT/MODIFIER
\d{6}
rename
검색되어 교체될 패턴입니다. 소수점 6자리입니다.$
일치하는 하위 문자열을 저장하는 변수입니다\d{6}
(이 경우 "substring"은 int입니다).sprintf("%06",($&-1))
에 저장된 값을 검색하여$
감소시키고 해당 값을 대체 값으로 반환합니다. 선행 0을 처리하는 데 사용 됩니다%06
.e
rename
대체 항목이 Perl 문으로 평가되고 해당 반환 값이 대체 텍스트로 사용되도록 지정합니다 .-v
rename
echo가 수행하는 작업을 수행 하도록 합니다 .
더욱 안전해지려면 이 플래그를 사용하여 수행할 작업만 알려주고 실행하지 않도록 하십시오 -n
.rename
이는 감소에만 작동하는 것으로 보이므로 주의해서 처리하십시오.