대략 이름을 바꿔야합니다. 70,000 개 파일 예를 들면 :에서 sb_606_HBO_DPM_0089000
에 sb_606_dpm_0089000
등
숫자 범위는에서 0089000
로 이동 합니다 0163022
. 이름의 첫 부분 만 변경하면됩니다. 모든 파일은 단일 디렉토리에 있으며 순차적으로 번호가 매겨집니다 (이미지 시퀀스). 숫자는 변경되지 않아야합니다.
내가 이것을 bash에서 시도하면 ‘인수 목록이 너무 길다’는 소리가 난다.
편집하다:
먼저 단일 파일의 이름을 바꾸려고했습니다 mv
.
mv sb_606_HBO_DPM_0089000.dpx sb_606_dpm_0089000.dpx
그런 다음 범위의 이름을 바꾸려고했습니다 (지난 주에 파일로드를 이동하는 방법을 배웠으므로 동일한 이름의 구문을 사용하여 파일 이름을 바꿀 수 있다고 생각했습니다 …). 나는 다음과 같은 것을 시도 했다고 생각한다 .
mv sb_606_HBO_DPM_0{089000..163023}.dpx sb_606_dpm_0{089000..163023}.dpx
답변
한 가지 방법은 사용하는 것입니다 find
함께 -exec
하고 +
옵션을 선택합니다. 이것은 인수 목록을 구성하지만, 최대 인수 목록을 초과하지 않고 모든 파일에서 작동하는 데 필요한만큼의 호출로 목록을 나눕니다. 모든 인수가 동일하게 취급 될 때 적합합니다. 이것은의 경우 rename
로 생각하지 mv
.
Perl 이름 바꾸기를 설치해야 할 수도 있습니다.
sudo apt install rename
그런 다음 예를 들어 사용할 수 있습니다.
find . -maxdepth 1 -exec rename -n 's/_HBO_DPM_/_dpm_/' {} +
-n
실제로 파일 이름을 바꾸려면 테스트 후 제거하십시오 .
답변
세 가지 대안을 제안하겠습니다. 각각은 간단한 한 줄 명령이지만, 처리 할 파일이 동일한 직접 경로의 다른 파일과 혼합되는 경우를 대비하여보다 복잡한 경우에 대한 변형을 제공합니다.
mmv
동일한 이름
의 패키지 에서 mmv 명령 을 사용합니다 .
mmv '*HBO_DPM*' '#1dpm#2'
인수는 문자열로 전달되므로 셸에서 glob 확장이 발생하지 않습니다. 이 명령은 정확히 두 개의 인수를받은 다음 파일 수에 대한 제한없이 내부에서 해당 파일을 찾습니다. 또한 위의 명령은 첫 번째 glob과 일치하는 모든 파일의 이름이 바뀌어야한다고 가정합니다. 물론보다 구체적으로 설명 할 수 있습니다.
mmv 'sb_606_HBO_DPM_*' 'sb_606_dpm_#1'
동일한 디렉토리에 요청 된 번호 범위를 벗어난 파일이있는 경우이 답변에서 더 아래에 주어진 루프 오버 번호를 사용하는 것이 좋습니다. 그러나 적절한 패턴으로 일련의 mmv 호출을 사용할 수도 있습니다.
mmv 'sb_606_HBO_DPM_0089*' 'sb_606_dpm_0089#1' # 0089000-0089999
mmv 'sb_606_HBO_DPM_009*' 'sb_606_dpm_009#1' # 0090000-0099999
mmv 'sb_606_HBO_DPM_01[0-5]*' 'sb_606_dpm_01#1#2' # 0100000-0159999
mmv 'sb_606_HBO_DPM_016[0-2]*' 'sb_606_dpm_016#1#2' # 0160000-0162999
mmv 'sb_606_HBO_DPM_01630[01]?' 'sb_606_dpm_01630#1#2' # 0163000-0163019
mmv 'sb_606_HBO_DPM_016302[0-2]' 'sb_606_dpm_016302#1' # 0163020-0163022
숫자를 반복하다
설치를 피하거나이 범위 밖의 일치를 피하면서 숫자 범위로 선택해야하고 74,023 명령 호출을 기다릴 준비가 되었다면 일반 bash 루프를 사용할 수 있습니다.
for i in {0089000..0163022}; do mv sb_606_HBO_DPM_$i sb_606_dpm_$i; done
시퀀스에 간격이 없기 때문에 이것은 특히 잘 작동합니다. 그렇지 않으면 소스 파일이 실제로 존재하는지 확인할 수 있습니다.
for i in {0089000..0163022}; do
test -e sb_606_HBO_DPM_$i && mv sb_606_HBO_DPM_$i sb_606_dpm_$i
done
for ((i=89000; i<=163022; ++i))
괄호 확장 과 달리 몇 년 전에 일부 Bash 릴리스 이후 선행 0을 처리합니다. 실제로 변경을 요청 했으므로 유스 케이스를 보게되어 기쁩니다.
추가 자료 : Bash 정보 페이지의 브레이스 확장 , 특히 관련 부분 {x..y[..incr]}
.
파일을 반복
또 다른 옵션은 해당 정수 범위를 반복하는 대신 적절한 glob를 반복하는 것입니다. 이 같은:
for i in *HBO_DPM*; do mv "$i" "${i/HBO_DPM/dpm}"; done
이 역시 mv
파일 당 한 번의 호출입니다. 그리고 루프는 요소의 긴 목록에 있지만 전체 목록은 하위 프로세스에 인수로 전달되지 않지만 bash에 의해 내부적으로 처리되므로 제한이 문제를 일으키지 않습니다.
추가 정보 : Bash 정보 페이지의 쉘 매개 변수 확장${parameter/pattern/string}
.
숫자 범위를 제공 한 숫자 범위로 제한하려면 해당 검사를 추가 할 수 있습니다.
for i in sb_606_HBO_DPM_+([0-9]); do
if [[ "${i##*_*(0)}" -ge 89000 ]] && [[ "${i##*_*(0)}" -le 163022 ]]; then
mv "$i" "${i/HBO_DPM/dpm}"
fi
done
여기에 ${i##pattern}
가장 긴 접두사 일치 제거 pattern
에서를 $i
. 가장 긴 접두사는 무엇이든, 밑줄, 0 또는 그 이상의 0으로 정의됩니다. 후자는 설정 되는 옵션 에 따라 *(0)
확장 된 glob 패턴 으로 작성됩니다 . 앞의 0을 제거하는 것은 숫자를 밑이 8이 아닌 밑이 10으로 취급하는 데 중요합니다. in 루프 인수는 파일이 동일하게 시작하지만 끝나지 않는 파일이있는 경우를 대비하여 하나 이상의 숫자와 일치하는 또 다른 확장 된 glob입니다. 번호.extglob
+([0-9])
답변
ARG_MAX
한계를 극복 하는 한 가지 방법 은 bash 쉘의 내장을 사용하는 것입니다 printf
.
printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'
전의.
rename -n 's/HBO_DPM/dpm/' sb_*
bash: /usr/bin/rename: Argument list too long
그러나
printf '%s\0' sb_* | xargs -0 rename -n 's/HBO_DPM/dpm/'
rename(sb_606_HBO_DPM_0089000, sb_606_dpm_0089000)
.
.
.
rename(sb_606_HBO_DPM_0163022, sb_606_dpm_0163022)
답변
find . -type f -exec bash -c 'echo $1 ${1/HBO_DPM/dpm}' _ {} \;
./sb_606_HBO_DPM_0089000 ./sb_606_dpm_0089000
find
.
모든 파일의 현재 디렉토리 에 있고 파일 을 하나씩 바꾸면서 -type f
찾은 파일의 이름을 바꾸십시오.$1
HBO_DPM
dmp
-exec ... \;
교체 echo
로 mv
이름 변경을 수행 할 수 있습니다.
답변
다음과 같은 작은 파이썬 스크립트를 작성할 수 있습니다.
import os
for file in os.listdir("."):
os.rename(file, file.replace("HBO_DPM", "dpm"))
파일이 들어 rename.py
있는 폴더에서 와 같이 텍스트 파일로 저장 한 다음 해당 폴더의 터미널로 이동하십시오.
python rename.py
답변
파일별로 파일을 만들 수 있습니다 (시간이 걸릴 수 있음)
sudo apt install util-linux # if you don't have it already
for i in *; do rename.ul HBO_DPM dpm "$i"; done
rename
다른 답변에 사용 된 Perl과 마찬가지로 rename.ul
옵션 -n
또는 --no-act
테스트가 있습니다.
답변
나는 나의 가장 친한 친구 sed
를 파티에 초대 한 사람이 없다는 것을 안다 . :). 다음 for
루프는 목표를 달성합니다.
for i in sb_606_HBO_DPM*; do
mv "$i" "$(echo $i | sed 's/HBO_DPM/dpm/')";
done
이러한 작업을위한 많은 도구가 있으므로 가장 이해하기 쉬운 도구를 선택하십시오. 이것은 간단하고 쉽게이 또는 다른 목적에 맞게 변경됩니다 …