다음과 같은 특수 문자가 포함된 파일이 포함된 여러 디렉터리와 하위 디렉터리가 있습니다.
robbie@phil:~$ ls test�sktest.txt
test?sktest.txt
찾기는 이스케이프 시퀀스를 나타냅니다.
robbie@phil:~$ find test�sktest.txt -ls
424512 4000 -rwxr--r-x 1 robbie robbie 4091743 Jan 26 00:34 test\323sktest.txt
콘솔에 이름을 입력할 수 있는 유일한 이유는 탭 완성 때문입니다. 이는 수동으로 이름을 바꿀 수도 있고 특수 문자를 제거할 수도 있음을 의미합니다.
LC_ALL을 UTF-8로 설정했는데 도움이 되지 않는 것 같습니다(새 쉘에서도 도움이 되지 않습니다).
robbie@phil:~$ echo $LC_ALL
en_US.UTF-8
내 Mac에서 컴퓨터에 연결하기 위해 SSH를 사용하고 있습니다. 우분투 설치는 다음과 같습니다.
robbie@phil:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=7.10
DISTRIB_CODENAME=gutsy
DISTRIB_DESCRIPTION="Ubuntu 7.10"
쉘은 Bash이고 TERM은 xterm-color로 설정됩니다.
이 파일은 오랫동안 존재해 왔으며 Ubuntu 설치를 사용하여 생성되지 않았습니다. 그래서 시스템 인코딩 설정이 무엇인지 알 수 없습니다.
나는 다음을 시도했습니다 :
find . -type f -ls | sed 's/[^a-zA-Z0-9]//g'
하지만 내가 원하는 모든 작업을 수행하는 솔루션을 찾을 수 없습니다.
- 표시할 수 없는 문자가 있는 모든 파일을 식별합니다(너무 많은 문자는 위에서 무시됨).
- 디렉토리 트리의 모든 파일에 대해 (재귀적으로) mv oldname newname을 수행하십시오.
- (선택 사항) 특수 문자(예: ä)를 a(필수는 아니지만 유용할 것임)로 음역합니다.
또는
- 이러한 파일은 모두 올바르게 표시됩니다(파일을 열려고 할 때 응용 프로그램에 오류가 없습니다).
모든 파일을 반복하고 이동하는 것과 같은 몇 가지 문제가 있지만 파일을 식별하고 mv 명령에 대해 올바르게 형식을 지정하는 것이 어려운 부분인 것 같습니다.
올바르게 표시되지 않는 이유나 올바른 인코딩을 "추측"하는 방법에 대한 추가 정보도 환영합니다. (convmv를 시도했지만 정확히 내가 원하는 대로 작동하지 않는 것 같습니다.http://j3e.de/linux/convmv/)
답변1
�
이름에 잘못된 UTF-8 바이트 시퀀스가 포함되어 있기 때문에 이 잘못된 문자가 표시되는 것 같습니다 . 일반적인 유닉스 파일 시스템(사용자 시스템 포함)의 파일 이름은 바이트 문자열이며 사용할 인코딩을 결정하는 것은 응용 프로그램에 달려 있습니다. 요즘 UTF-8 사용이 추세가 되었지만 보편적이지 않습니다. 특히 순수 ASCII가 불가능한 로케일과 UTF-8이 존재하기 전에 다른 인코딩이 사용된 지역에서는 더욱 그렇습니다.
LC_CTYPE=en_US.iso88591 ls
ISO-8859-1(latin-1)에서 파일 이름이 적합한지 확인해보세요 . 그렇지 않은 경우 다른 로케일을 사용해 보십시오. LC_CTYPE
여기서는 로케일 만 중요합니다.
UTF-8 로케일에서 다음 명령은 유효한 UTF-8이 아닌 이름을 가진 모든 파일을 표시합니다.
grep-invalid-utf8 () {
perl -l -ne '/^([\000-\177]|[\300-\337][\200-\277]|[\340-\357][\200-\277]{2}|[\360-\367][\200-\277]{3}|[\370-\373][\200-\277]{4}|[\374-\375][\200-\277]{5})*$/ or print'
}
find | grep-invalid-utf8
다른 로케일에서 더 의미가 있는지 확인할 수 있습니다.녹음또는상:
find | grep-invalid-utf8 | recode latin1..utf8
find | grep-invalid-utf8 | iconv -f latin1 -t utf8
여러 파일 이름이 특정 인코딩(예: latin1)으로 되어 있음을 확인한 후 이름을 바꾸는 한 가지 방법은 다음과 같습니다.
find | grep-invalid-utf8 |
rename 'BEGIN {binmode STDIN, ":encoding(latin1)"; use Encode;}
$_=encode("utf8", $_)'
이것은 펄을 사용합니다이름을 바꿔라이 명령은 Debian 및 Ubuntu에서 사용할 수 있습니다. -n
실제로 파일 이름을 바꾸지 않고도 무엇을 할 것인지 보여주기 위해 이를 전달할 수 있습니다 .
답변2
나는 이것이 오래된 질문이라는 것을 알고 있지만 밤새도록 비슷한 해결책을 찾고 있었습니다. 몇 가지 유용한 팁을 찾았지만 내 요구사항에 꼭 맞지 않아서 내가 찾고 있던 올바른 결과를 얻기 위해 몇 가지 팁을 혼합하고 일치시켜야 했습니다.
특수 문자를 제거하고 (.) 점으로 바꾸세요.
for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done
cronjob에서 사용하기 위해 매분 실행되는 다음을 수행했습니다.
*/1 * * * * cd /path/to/files/ && for f in *.txt; do mv "$f" `echo $f | sed "s/[^a-zA-Z0-9.]/./g"`; done >/dev/null 2>&1
누군가가 이것이 나를 행복하게 해주기 때문에 도움이 되기를 바랍니다 :)
답변3
이제 원격 측의 파일 이름에 어떤 인코딩이 사용되는지 알면("latin1" - 첫 번째 답변의 설명에 따라) 다음을 수행할 수도 있습니다.두 번째 방법-- 로컬 터미널을 실행하고SSH이런 식으로원격 파일 이름이 올바르게 표시됩니다(첫 번째 방법: 이름 바꾸기 대신)..
좋다나, 다음과 같이 특정 인코딩에서 작동하는 터미널을 로컬에서 시작할 수 있습니다.
LC_ALL=en_US.latin1 xvt &
xvt
터미널 프로그램을 나타냅니다.
어쩌면 기존 로케일을 그렇게 부르는데 제가 가정한 것이 en_US.iso88591
아닐 수도 있습니다.en_US.latin1
답변4
이는 대량 요구 사항을 충족하지 않지만 비슷한 이름을 가진 여러 버전의 파일이 있고 이상한 문자만 다른 유사한 문제에 직면했습니다. 불행하게도 이는 범죄자의 이름을 바꾸기 위해 일반적인 와일드카드 트릭을 사용할 수 없음을 의미합니다.
마지막으로 Filezilla를 SFTP 클라이언트로 사용하여 연결하고, 파일을 찾아보고, GUI를 사용하여 이름을 바꿨습니다. Filezilla는 의심스러운 문자를 매우 잘 처리합니다.