Las respuestas existentes se centran en explicar por qué-e
funciona case-INsensitively en OSX, y por qué lo hace por buenas razones en general.
Sin embargo, veces te quieren saber si existe un camino en forma exacta de mayúsculas, porque a pesar de que el sistema de archivos no puede cuidar, otro software de puede.
Perl en sí es un ejemplo:
En OSX, Perl (por desgracia) acepta variaciones de caso de un nombre de módulo con la declaración use
, porque use
realiza búsquedas sistemas de ficheros, que son sensibles a mayúsculas inherentemente. Sin embargo, realmente usando ese módulo NO funcionará, a menos que el nombre del módulo sea CASO-EXACTO; por ejemplo: perl -MData::Dumper -E 'print Dumper(666)'
(OK) frente a perl -Mdata::dumper -E 'print Dumper(666)'
(se rompe, porque aunque cargando el módulo parece tener éxito, no se puede acceder a sus elementos, como Dumper()
).
El problema en pocas palabras: si existe camino /FOO/BAR
en su HFS + sistema de archivos (en OSX),
-e '/foo/bar'
o cualquier variación caso del mismo indicará que existe el camino, y no hay manera fácil de determinar si /foo/bar
es un caso -representación exacta o, más en general, cuál es el verdadero caso de la ruta.
Aquí hay una aplicación ingenua que utiliza el siguiente enfoque:
- se aprovecha del hecho de que
File::Glob::bsd_glob()
por defecto actúa casos y con sensibilidad incluso en el OSX, cuyo sistema de archivos (HFS +) es por caso- por defecto Insensible.
- Sin embargo, la coincidencia solo se produce para los componentes de ruta que contienen un patrón real , mientras que nombres literales se devuelven tal cual.
- Por lo tanto, un globo se construye a partir de la ruta de entrada que convierte cada componente de trayectoria en un patrón de auto coincidencia, encerrando el primer carácter. de cada componente de ruta en [] (un conjunto que solo coincide con ese carácter en sí).
sub istruecasepath {
use File::Glob qw/bsd_glob/;
return defined bsd_glob join '', map {
m`^(//?|\.|\.\.|)$` ?
$_
:
'[' . substr($_, 0, 1) . ']' . substr($_, 1)
} split m`(//?)`, shift;
}
Esto funciona con las siguientes limitaciones:
- la ruta de entrada no debe contener caracteres no ASCII
- la ruta de entrada no debe contener metacaracteres patrón (es decir, el camino los componentes no deben contener caracteres literales, como
*
o [
, que podrían interpretarse erróneamente como caracteres de patrón (globbing).
Aquí hay una implementación robusta , que implica trabajo adicional para superar estas limitaciones; Se espera que la entrada como una cadena Unicode:
sub istruecasepath {
use File::Glob qw/:bsd_glob/;
use Unicode::Normalize;
# Convert to NFD Unicode normal form, because that's how HFS+ stores names.
my $path_nfd_quoted = NFD shift;
# \-quote glob characters and '\' instances.
$path_nfd_quoted =~ s/[][{}*?\\]/\\$&/; #/
my $glob = join '', map {
m`^(//?|\.|\.\.|)$` ?
$_
:
do { my $len = m`^\\` ? 2 : 1; '[' . substr($_, 0, $len) . ']' . substr($_, $len) }
} split m`(//?)`, $path_nfd_quoted;
return defined bsd_glob "$glob", GLOB_QUOTE;
}
Como beneficio adicional, aquí está una variante que vuelve la trayectoria exacta de mayúsculas tal como se almacena en el sistema de archivos, dada una variación caso:
sub getruecasepath {
use File::Glob qw/:bsd_glob/;
use Unicode::Normalize;
# Convert to NFD Unicode normal form, because that's how HFS+ stores names.
my $path_nfd_quoted = NFD shift;
# \-quote glob characters and '\' instances.
$path_nfd_quoted =~ s/[][{}*?\\]/\\$&/; #/
my $glob = join '', map {
m`^(//?|\.|\.\.|)$` ?
$_
:
do { my $len = m`^\\` ? 2 : 1; '[' . substr($_, 0, $len) . ']' . substr($_, $len) }
} split m`(//?)`, $path_nfd_quoted;
my $path_truecase = bsd_glob "$glob", GLOB_NOCASE | GLOB_QUOTE;
return if not defined $path_truecase;
# !! bsd_glob() returns a raw UTF8-encoded byte sequence that isn't
# !! automatically reconverted to a Unicode string, so we must do it
# !! manually here.
utf8::decode($path_truecase);
return $path_truecase;
}
Su ''$ fileName'' no debe usar comillas, y si lo hace, debe usar comillas dobles (a menos que sea perverso, como yo, y preceda las comillas simples con' qq' $ fileName ' '). Del mismo modo, la notación '
Además, su título dice 'distingue entre mayúsculas y minúsculas' y la pregunta dice 'insensible a mayúsculas y minúsculas'; ¿Qué es lo que realmente quieres? –
'-e' simplemente pasa el argumento a la llamada' stat' de su sistema. – ikegami