인코딩이 잘못된 파일을 대량으로 바꾸거나 인코딩 된 문자를 대량으로 바꾸는 방법은 무엇입니까? Title – additional Info/B�ndname – 07 –

데비안 서버가 있고 인터넷 라디오 방송국을위한 음악을 호스팅하고 있습니다. 예를 들어 많은 파일에 잘못된 인코딩이있어 파일 이름과 경로에 문제가 있습니다.

./music/Bändname - Some Title - additional Info/B�ndname - 07 - This Title Is Cörtain, The EncÃding Not.mp3

이상적으로는 문자 A-Z/ a-z숫자 0-9또는 대시 -/ 밑줄 이 아닌 모든 것을 제거하고 싶습니다 _… 결과는 다음과 같습니다.

./music/Bndname-SomeTitle-additionalInfo/Bndname-07-ThisTitleIsCrtain,TheEncdingNot.mp3

많은 파일과 디렉토리를 위해 이것을 달성하는 방법은 무엇입니까?

이 비슷한 질문을 보았습니다 : 특수 문자가있는 파일 이름 바꾸기 (또는 올바르게 표시)

그러나 이것은 인코딩 만 수정하므로 위에서 설명한 것처럼보다 엄격한 접근 방식을 선호합니다.



답변

파일 디렉토리의 이름을 동시에 바꾸려면 일부 문제가 발생합니다 . 파일 이름 만 바꾸면 충분합니다. 그러나 디렉토리의 이름도 바꾸고 싶습니다. 당신은 할 수 단순히 mv Motörhead/Encöding Motorhead/Encoding때문에 Motorhead호출의 시간에 존재하지 않습니다.

따라서 모든 파일과 폴더를 우선적으로 탐색 한 다음 현재 파일이나 폴더의 이름 만 바꿉니다. 다음은 findOS X에서 GNU 및 Bash 4.2.42에서 작동합니다.

#!/usr/bin/env bash
find "$1" -depth -print0 | while IFS= read -r -d '' file; do
  d="$( dirname "$file" )"
  f="$( basename "$file" )"
  new="${f//[^a-zA-Z0-9\/\._\-]/}"
  if [ "$f" != "$new" ]      # if equal, name is already clean, so leave alone
  then
    if [ -e "$d/$new" ]
    then
      echo "Notice: \"$new\" and \"$f\" both exist in "$d":"
      ls -ld "$d/$new" "$d/$f"
    else
      echo mv "$file" "$d/$new"      # remove "echo" to actually rename things
    fi
  fi
done

new="${f//[\\\/\:\*\?\"<>|]/}"Windows가 처리 할 수없는 항목을 바꾸 려면를 사용하여 정규식을 변경할 수 있습니다.

이 스크립트를로 저장 rename.sh하고로 실행 가능하게 만드십시오 chmod +x rename.sh. 그런 다음처럼 호출하십시오 rename.sh /some/path.

파일 이름 충돌 (“ Notice”알림) 을 해결하십시오 .

당신이 절대적으로 확신 한다면 는 바로 교체하지의 제거 echo그냥 무엇을 인쇄하는 대신 실제로 이름 바꾸기 것에 스크립트에서.

안전을 위해 작은 파일 하위 집합에서 먼저 테스트하는 것이 좋습니다.


옵션 설명

여기에 무슨 일이 있는지 설명하려면 :

  • -depth디렉토리가 깊이 우선으로 재 확보되도록하여 모든 것을 “롤업”할 수 있습니다. 일반적으로 find다르게 순회합니다 (단 , 너비 우선은 아님).
  • -print0보장하는 find출력은 우리가 그것을 읽을 수 있도록, 널 (null)로 구분이다 read -d ''file 가변. 이렇게하면 공백이있는 파일과 줄 바꿈을 포함하여 모든 종류의 이상한 파일 이름을 처리하는 데 도움이됩니다.
  • 우리는 파일의 디렉토리를 얻을 것이다 dirname . 항상 변수를 올바르게 인용하는 것을 잊지 마십시오. 그렇지 않으면 공백이나 글러브 문자가있는 경로가이 스크립트를 손상시킵니다.
  • 로 실제 파일 이름 (또는 디렉토리 이름)을 얻습니다 basename.
  • 그런 다음 $fBash의 문자열 교체 기능 을 사용하여 유효하지 않은 문자를 제거합니다 . 유효하지 않음은 소문자 또는 대문자, 숫자, 슬래시 ( \/), 점 ( \.), 밑줄 또는 빼기 하이픈이 아닌 것을 의미합니다.
  • $f이미 깨끗한 경우 (정리 된 이름이 현재 이름과 동일) 건너 뜁니다.
  • 경우 $new이미 디렉토리에 존재하는 $d(예를 들어, 당신이라는 이름의 파일이 resumerésumé같은 디렉토리에) 경고를 실행합니다. 일부 시스템에서는 이름을 바꾸고 싶지 않습니다.mv foo foo 문제가 발생 . 그렇지 않으면,
  • 마지막으로 원래 파일 (또는 디렉토리)의 이름을 새 이름으로 바꿉니다.

이 때문에 단지 이름 변경, 깊은 계층에 역할을 할 Motörhead/EncödingMotorhead/Encoding두 단계로 이루어집니다 :

  1. mv Motörhead/Encöding Motörhead/Encoding
  2. mv Motörhead Motorhead

이렇게하면 모든 교체가 올바른 순서로 수행됩니다.


예제 파일 및 테스트 실행

기본 폴더의 일부 파일을 다음과 같이 가정합니다 test.

test
test/Motörhead
test/Motörhead/anöther_file.mp3
test/Motörhead/Encöding
test/Randöm
test/Täst
test/Täst/Töst
test/with space
test/with-hyphen.txt
test/work
test/work/resume
test/work/résumé
test/work/schedule

다음은 디버그 모드에서 실행 ( ) echo앞에 실행 된 결과 mv, 즉 호출 될 명령 및 충돌 경고입니다.

mv test/Motörhead/anöther_file.mp3 test/Motörhead/another_file.mp3
mv test/Motörhead/Encöding test/Motörhead/Encoding
mv test/Motörhead test/Motorhead
mv test/Randöm test/Random
mv test/Täst/Töst test/Täst/Tost
mv test/Täst test/Tast
mv test/with space test/withspace
Notice: "resume" and "résumé" both exist in test/work:
-rw-r—r--  …  …  test/work/resume
-rw-r—r--  …  …  test/work/résumé

에 대한 메시지의 부재를 주목하라 with-hyphen.txt, schedule그리고 test그 자체.


답변

정확히 원하는 것이 아니라는 것을 알고 있지만 원래 인코딩을 알고 있다면 convmv인코딩을 UTF-8로 변경하여 대부분의 문제를 해결할 수 있습니다.

이것은 유효하지 않은 인코딩 된 폴란드 파일 이름이있는 폴더에서 나를 위해 일했습니다.

convmv -f cp1250 -t utf8 -r .

이 명령은 실제로 이름을 바꾸지 않습니다. --notest파일 이름을 바꾸려면 옵션을 추가 하십시오.


답변

이름 바꾸기에 대해 물었습니다.

그러나 MusicBrainz Picard 와 같은 소프트웨어를 사용하면 문제를 쉽게 피할 수 있습니다 .

음악을 식별하고 (오디오 핑거 프린팅) 거대한 MusicBrainz 데이터베이스 에서 필요한 모든 데이터 (표지 이미지 포함)를 다운로드하고 컬렉션을 원하는 패턴에 맞출 수 있도록 파일을 이동할 수 있습니다. 나는 수년간 그것을 사용하고 있으며 항상 Cyrilic에서 Arabic에 이르기까지 완벽하게 작동했습니다. 물론 (적어도 라틴어 기반 스크립트의 경우) ASCII로 변환 할 수도 있습니다.

이 방법을 사용하면 파일을 읽고 완벽하게 사용할 수 있다면 컬렉션의 지저분하고 이름이 불분명 한 것이 실제로 중요하지 않습니다.

(내가 무료라고 언급 했습니까? 자유 언론에서나 무료 맥주 에서처럼? 소프트웨어와 데이터베이스 모두 ..?


답변