대부분의 Linux 파일 시스템에서 NUL( \0
)은 경로에서 유일하게 유효하지 않은 문자입니다( /
경로 구분 기호로 예약되어 있음).Windows에는 유효한 경로에 대한 복잡한 규칙 세트가 있습니다.. 경로를 자동으로 복구하는 대신(위험, 한 파일이 다른 파일을 덮어쓸 수 있음)Windows와 호환되지 않는 디렉터리에서 모든 경로를 찾는 방법은 무엇입니까?
원래 질문은 내 것이었어구글 드라이브폴더는 다음을 사용하여 설치된 드라이브에 있습니다.ext2fs, 하지만 공식 Gdrive 클라이언트에서는 수천 개의 파일을 동기화할 수 없다고 말합니다. 오류 메시지를 찾을 수 없으며 파일을 보여달라고 요청하면 무기한 중단됩니다. 클라이언트 또는 OS를 다시 시작해도 도움이 되지 않았지만 예감이 들었습니다.Windows와 호환되지 않는 경로를 수정하세요.Gdrive가 취소됩니다. 효과가 있었던 것 같습니다...
답변1
예약된 이름/문자가 있는 경로:
LC_ALL=C find . -name '*[[:cntrl:]<>:"\\|?*]*' \
-o -iname 'CON' \
-o -iname 'PRN' \
-o -iname 'AUX' \
-o -iname 'NUL' \
-o -iname 'COM[1-9]' \
-o -iname 'LPT[1-9]' \
-o -name '* ' \
-o -name '?*.'
시험:
$ cd -- "$(mktemp --directory)"
$ touch foo \\ LPT9 'space ' 'dot.'
$ LC_ALL=C find . -name '*[[:cntrl:]<>:"\\|?*]*' -o -iname 'CON' -o -iname 'PRN' -o -iname 'AUX' -o -iname 'NUL' -o -iname 'COM[1-9]' -o -iname 'LPT[1-9]' -o -name '* ' -o -name '?*.'
./dot.
./space
./LPT9
./\
대소문자를 무시할 때 동일한 경로(개행 문자가 포함된 경로에서는 작동하지 않습니다.):
find . | sort | LC_ALL=C tr '[:upper:]' '[:lower:]' | uniq -c | grep -v '^ 1 ' | cut -c '9-'
시험:
$ cd -- "$(mktemp --directory)"
$ touch foo bar BAR
$ find . | sort | LC_ALL=C tr '[:upper:]' '[:lower:]' | LC_ALL=C uniq -c | grep -v '^ 1 ' | cut -c '9-'
./bar
경로 길이가 다음을 초과합니다 MAX_PATH
(260자):
find "$PWD" | while IFS= read -r path
do
if [ "${#path}" -gt 260 ]
then
printf '%s\n' "$path"
fi
done
시험:
$ cd -- "$(mktemp --directory)"
$ touch foo 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
$ find "$PWD" | while IFS= read -r path
> do
> if [ "${#path}" -gt 260 ]
> then
> printf '%s\n' "$path"
> fi
> done
/tmp/tmp.HEANyAI8Hy/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
답변2
Perl 솔루션의 경우 이 모듈을 사용할 수 있습니다 Win32::Filenames
.
http://search.cpan.org/~bch/Win32-Filenames-0.01/lib/Win32/Filenames.pm
이 모듈을 사용하는 간단한 프로그램:
#!/usr/bin/env perl
use strict;
use warnings;
use Win32::Filenames qw(validate sanitize);
while ( my $filename = shift ) {
printf( "checking filename %s\t", $filename );
if ( validate($filename) ) {
print("ok.\n");
}
else {
printf( "failed, try this instead: %s\n", sanitize($filename) );
}
}
하나 이상의 파일 이름을 사용하여 명령줄에서 호출할 수 있습니다.
$ ./check.pl '<a>' 'hi?' '"right"' 'pipe|me'
checking filename <a> failed, try this instead: -a-
checking filename hi? failed, try this instead: hi-
checking filename "right" failed, try this instead: -right-
checking filename pipe|me failed, try this instead: pipe-me
전체 파일 계층의 경우:
$ find . -exec basename {} \; | xargs ./check.pl