파일 이름의 모든 콜론을 터미널로 교체


12

EXT4로 포맷 된 HDD에 GB의 음악이 있습니다. 이 파일들을 FAT 포맷 HDD 파티션으로 옮기고 싶습니다. 그러나 이름에 ":"가 있기 때문에 대부분의 파일을 이동할 수 없습니다 (예 : 오페라의 경우 "Act 2 : ....."). 모든 파일의 이름을 "XXXX : XXXX"에서 "XXXX-XXXX"로 바꾸는 명령 줄이 있습니까?

답변:


25

모든 파일이 단일 디렉토리에있는 경우 다음을 시도하십시오.

rename 's|:|-|g' *

(* 원하는 경우 더 제한적인 것으로 변경할 수 있습니다)

디렉토리 트리에 많은 파일이있는 경우 트리의 기초에서이 파일을 시도하십시오.

find . -name "*:*" -exec rename 's|:|-|g' {} \;

당신은 옵션을 추가 할 수 있습니다 -n직후 rename실제로 그 일을하지 않고 어떻게 할 것인지 당신을 말하게 할 수 있습니다. 이것은 실수로 다른 파일이나 다른 것을 밟지 않도록 도와줍니다 ...


1
단일 디렉토리 솔루션은 작동하지만 디렉토리 자체에 이름이 : s 인 경우 중첩 솔루션은 작동하지 않습니다. find .서브 디렉토리 이름의 출력이 내용보다 우선하기 때문입니다. 따라서 파일이 /1:/2:먼저 /1:/있으면 이름이로 변경됩니다 /1-/. 존재하지 않기 때문에 이름 /1:/2:을 바꿀 수 없습니다 . /1-/2-/1:/2:
S Prasanth

1
디렉토리 : find . -type d -readable -writable -exec rename 's|:|-|g' {} \;그리고 파일 :find . -type f -readable -writable -exec rename 's|:|-|g' {} \;

@Christopher 이름에 두 개의 레벨이있는 ​​디렉토리가 있으면 디렉토리 명령이 실패합니다. 예 : / 1 : / 2 : / 여기서 2 :는 디렉토리입니다. 물론 Ryan의 상황에서 그렇지 않은 경우 작동합니다.
S Prasanth

여러 수준의 하위 디렉토리에 대해 다음을 사용하십시오 for i in {1..20}; do find . -maxdepth $i -mindepth $i -name "*:*" -exec rename 's|:|-|g' {} \;; done.. 20을 dir의 최대 깊이로 변경하십시오. 구조. 정확할 필요는 없습니다. 더 클 수 있습니다. 그래도 매우 큰 숫자로 설정하면 시간이 걸립니다.
S Prasanth

0

나는 내 리눅스 머신에 있지 않기 때문에 대략적인 정보 만 줄 수 있습니다.

Linux에는 rename다른 입력, 정규식 또는 정규식과 함께 작동 하는 명령 줄 유틸리티가 있습니다. 원하는 이름을 바꾸려면 파일에 "s / : /-/"와 같은 정규식과 함께 사용할 수 있어야합니다.

안전을 위해 작은 배치로 수행하거나 시뮬레이션으로 첫 번째 테스트를 수행하십시오 (이름 바꾸기에는 실제로 이름을 바꾸지 않고 파일의 이전 이름과 새 이름을 제공하는 플래그가 있음).


0

이것은 파일이 반드시 동일한 디렉토리에 있지 않은 경우를 처리하는 파이썬의 솔루션입니다.

import os
torename = []
rootdir = "The main directory"
logfile = "Path to log file" #Eg: logfile = "/home/prasanth/renamelog"
for (path, dirs, files) in os.walk(rootdir):
    for dirname in dirs:
        if ':' in dirname:
            torename.append(os.path.join(path, dirname))
    for filename in files:
        if ':' in filename:
            torename.append(os.path.join(path, filename))

print "No of files/dirs to rename =", len(torename)
a = raw_input("Continue? (y/n) ")
if a == 'y':
    torename.reverse()
    for oldname in torename:
        directory, filename = os.path.split(oldname)
        newname = os.path.join(directory, filename.replace(':', '-'))
        command = 'mv %s %s > /dev/null' % (repr(oldname), repr(newname))
        os.system(command)
        f = open(logfile, 'a')
        f.write(oldname + '\n')
        f.close()
else:
    print "Aborted."
  1. 이것을 파일 (예 : rename.py)에 저장하십시오.
  2. rootdir고려중인 가장 바깥 쪽 디렉토리로 변경하십시오 (/로 시작하는 완전한 경로 이름을 사용하십시오. ~ 허용과 같은 축약 형 또는 env 변수 없음). 특수 문자 앞에 \를 넣을 필요가 없습니다. 예를 들어 가장 바깥 쪽 디렉토리가 /.../My HDD 인 경우 rootdir = "/.../My HDD"NOT rootdir = "/.../My\ HDD"( "s"참고) [파이썬에 익숙하지 않기 때문에이 내용은 명시 적입니다. 예정된.]
  3. logfile원하는 로그 파일 위치로 변경하십시오 . 결국이 파일에는 나중에 참조 할 수 있도록 이름이 바뀐 파일 목록이 포함됩니다.
  4. 전화하십시오 python rename.py.

경고 : 전체 GB 음악을 위험에 빠뜨리기 전에 작은 샘플을 테스트하십시오.

세부 사항 : 이름 바꾸기는 가장 안쪽 파일부터 바깥쪽으로 수행됩니다.


0

나는 이것이 매우 오래된 게시물이라는 것을 알고 있습니다. AeroGT80의 재귀 솔루션은 매우 철저하지만 매우 느립니다. 느린 서버에서 약 30 분 동안 실행했으며 약 절반 만 완료했습니다. 약 300 개의 하위 디렉토리에 약 73,000 개의 파일이 있다고 생각합니다.

아래의 솔루션은 훨씬 빠르게 작동합니다 (AeroGT80의 비 재귀 솔루션을 사용하여 각 파일 대신 하나씩 디렉토리의 모든 파일에서 작동합니다). 유일한 문제는 하나의 디렉토리 깊이까지 내려가는 것이므로 (그의 솔루션처럼 완전히 재귀 적이지는 않지만) 쉽게 수정할 수 있다고 확신합니다.

#!/bin/bash
for D in *; do
        if [ -d "${D}" ]; then
                #echo "${D}"
                pushd "${D}" > /dev/null
                rename 's|:|-|g' *
                popd > /dev/null
        fi
done
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.