파일 이름에서 유효하지 않은 문자를 제거하는 방법?


47

이런 문자가 잘못된 파일이 있습니다

009_-_�%86ndringshåndtering.html

Æ파일 이름에 문제 가있는 곳입니다.

유효하지 않은 문자를 모두 제거하는 방법이 있습니까?

아니면 tr어떻게 든 사용할 수 있습니까?

echo "009_-_�%86ndringshåndtering.html" | tr ???

5
문자는 아마 (당신이 뭔가했다 않는 다른 파일 시스템은 보관되지 것 "무효"아니다 정말 FS에 불쾌한가). 로케일을 변경하여 (예 : UTF8로) 이름을 올바르게 표시 했습니까?
James O'Gorman

답변:


41

한 가지 방법은 sed를 사용하는 것입니다.

mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')

교체 file물론, 파일 이름으로. 문자, 숫자, 마침표, 밑줄 또는 대시가 아닌 것을 밑줄로 바꿉니다. 원하는대로 유지하기 위해 문자를 추가 또는 제거하거나 대체 문자를 다른 것으로 변경하거나 전혀 변경할 수 없습니다.


4
나는 다음을 사용했다 :f='file'; mv 'file' ${f//[^A-Za-z0-9._-]/_}
Louis

1
H. 아래 헤스 (과 : 함께 내 재미 주석)으로 최고의 솔루션을 봐
월 실라

31

나는 당신이 리눅스 박스에 있고 파일은 Windows 박스에 있다고 가정합니다. Linux는 파일 이름의 문자 인코딩으로 UTF-8을 사용하는 반면 Windows는 다른 것을 사용합니다. 이것이 문제의 원인이라고 생각합니다.

"convmv"를 사용합니다. 파일 이름을 한 문자 인코딩에서 다른 문자 인코딩으로 변환 할 수있는 도구입니다. 서유럽의 경우 다음 중 하나가 정상적으로 작동합니다.

convmv -r -f windows-1252 -t UTF-8 .
convmv -r -f ISO-8859-1 -t UTF-8 .
convmv -r -f cp-850 -t UTF-8 .

데비안 기반 Linux에 설치해야 할 경우 다음을 실행하여 설치할 수 있습니다.

sudo apt-get install convmv

매번 나를 위해 작동하며 원래 파일 이름을 복구합니다.

출처 : LeaseWebLabs


1
이것은 유망 해 보이지만 인코딩이 무엇인지 어떻게 알 수 있습니까? Save the current file in Word 97-2004 format\sco.workflowMac에서 (Microsoft Office를 통해) 생성 된 디렉토리 가 있으며 위의 인코딩은 영향을 미치지 않습니다.
Sridhar Sarnobat 님이

convmv는 기본적으로 "테스트"모드에서 실행되며, 여기서는 드라이 런만 수행하고 어떤 파일을 이동할지 알려줍니다. 그런 다음 --notest실제로 파일 이름을 바꾸는 옵션으로 다시 실행하라는 메시지가 표시됩니다 .
Kenny Rasschaert

16

파일 시스템을 통과하고 모든 파일을 수정하고 싶다고 가정합니까?

내가 할 방법은 다음과 같습니다

find /path/to/files -type f -print0 | \
perl -n0e '$new = $_; if($new =~ s/[^[:ascii:]]/_/g) {
  print("Renaming $_ to $new\n"); rename($_, $new);
}'

ASCII가 아닌 문자가 포함 된 모든 파일을 찾아 해당 문자를 밑줄 ( _)로 바꿉니다 . 그러나 새 이름을 가진 파일이 이미 있으면 덮어 씁니다. 이러한 경우를 확인하기 위해 스크립트를 수정할 수 있지만 간단하게 유지하기 위해 스크립트를 넣지 않았습니다.


13

https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-characters 에서 답변을 따르면 다음을 사용할 수 있습니다.

rename 's/[^\x00-\x7F]//g' *

여기서 *이름을 바꾸려는 파일과 일치합니다. 여러 디렉토리에서 수행하려면 다음과 같이하십시오.

find . -exec rename 's/[^\x00-\x7F]//g' "{}" \;

-n 인수를 사용하여 rename드라이 런을 수행하고 변경하지 않고 변경 내용을 확인할 수 있습니다.


예를 들어 ü 및 ä와 같은 외래 문자를 유지하기 위해 이것을 수정하는 방법이 있습니까?
Geek

두 번째 것만이 나를 위해 일했습니다. 모든 것이 같은 디렉토리에 있었기 때문에 차이점이 무엇인지 잘 모르겠습니다 ..?
Shautieh

1
@Shautieh : -n은 실제로 실행되지 않습니다. 나는 대답을 명확히 할 것이다.
naught101

많은 파일을 다룰 때 이름 바꾸기가 느려질 수 있습니다. 이 속도를 높이려면 수표를 찾기로 밀어 넣으십시오. 그래도 어떻게 해야할지 모르겠습니다.
isaaclw

13

깨진 USB 스틱에서 복구 된 깨진 파일 이름의 일부 일본어 파일이 있었고 위의 솔루션이 작동하지 않았습니다.

해독 패키지를 권장합니다.

해독 유틸리티는 작업하기 쉽도록 파일 이름을 바꿉니다. 그것은 공간과 다른 성가심을 제거합니다. 또한 8 비트 ASCII로 인코딩 된 Latin-1 (ISO 8859-1) 문자, UTF-8로 인코딩 된 유니 코드 문자 및 CGI 이스케이프 문자를 변환하거나 정리합니다.

사용법 예 :

detox -r -v /path/to/your/files
-r 서브 디렉토리로 재귀
-v 이름이 바뀐 파일에 대해 자세하게 설명하십시오. 
-n 드라이 런에 사용할 수 있습니다 (변경된 내용 만 표시).

2
이것은 훨씬 높아야 detox합니다. 바퀴를 재발 명하기 전에 모든 사람이 살펴볼 것을 촉구합니다 . 매뉴얼 페이지를 보면 유연성으로 인해 여기에서 제안 된 다른 모든 솔루션을 다루는 것을 볼 수 있습니다.
emk2203

에스겔 25:17-자선과 선의의 이름으로이 해결책을 찬성하는 사람은 복이 있습니다.
Jan Sila

직관적이지 않은 경로는 '.'일 수 없습니다. 데비안에서. '.'를 사용하는 경우 아무것도 찾지 못한다.
isaaclw

그것이 실제로 작동하는지 궁금합니다. 예를 들어 한자를 제거 / 교체하는 것처럼 的节奏啊보이지만 해당 문자는 유효한 파일 이름입니다.
林果 皞

5

이 셸 스크립트는 Linux / Windows와 FAT / NTFS / exFAT간에 파일을 이식 할 수 있도록 디렉토리를 반복적으로 삭제합니다. 제어 문자 /:*?"<>\|와 일부 예약 된 Windows 이름을 제거합니다 COM0.

sanitize() {
  shopt -s extglob;

  filename=$(basename "$1")
  directory=$(dirname "$1")

  filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')

  if (test "$filename" != "$filename_clean")
  then
    mv -v "$1" "$directory/$filename_clean"
  fi
}

export -f sanitize

sanitize_dir() {
  find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}

sanitize_dir '/path/to/somewhere'

리눅스는 이론적으로 덜 제한적인 ( /그리고 \0엄격 파일 이름에 금지)하지만 실제로는 여러 문자가 bash는 명령을 방해 (같은 *...) 그래서 그들은 또한 파일 이름에 피해야한다.

파일 이름 제한에 대한 훌륭한 소스 :


1
내가 찾은 것! 그러나 공백이있는 디렉토리를 지원하려면 따옴표를 추가하십시오. "$ 1"-depth -exec bash -c 'sanitize "$ 0"'{} \;
mmv-ru


0

이 단일 라이너를 사용하여 자막 파일에서 유효하지 않은 문자를 제거합니다.

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' |sed 's/\.\.\././g' |sed 's/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. * .srt 파일 만 처리 (* .srt 대신 *를 사용하여 모든 파일 처리 가능)
  2. 문자 A-Za-z, 숫자 0-9 및 마침표 "."를 제외한 다른 모든 문자를 제거합니다.
  3. 가능한 이중 또는 삼중 기간 제거
  4. 파일 이름에 유효하지 않은 문자가 있는지 확인
  5. true이면 mv 명령으로 파일 이름을 바꾸고 echo 명령으로 변경 한 내용을 출력합니다.

-2

파일의 경우 *; mv "$ file"$ (echo "$ file"| sed -e 's / [^ A-Za-z0-9.- ] / / g'); 완료 및


2
코드의 기능을 설명하고 올바른 형식을 사용해야합니다. 코드에서 이름에 충돌이 발생하여 파일이 삭제 될 수 있습니다. 그리고 백그라운드에서 전체를 실행하는 것은 어리석은 일입니다.
kasperd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.