A sintaxe a*
e *a*
é implementada pelo shell, não pelo comando ls
.
Quando você digita
ls a*
em seu prompt de shell, o shell expande a*
para uma lista de todos os arquivos existentes no diretório atual cujos nomes começam com a
. Por exemplo, pode expandir a*
para a sequência a1 a2 a3
e passar esses como argumentos para ls
. O comando ls
nunca vê o caractere *
; ele só vê os três argumentos a1
, a2
e a3
.
Para fins de expansão de caractere curinga, "arquivos" refere-se a todas as entidades no diretório atual. Por exemplo, a1
pode ser um arquivo normal, a2
pode ser um diretório e a3
pode ser um symlink. Todos eles têm entradas de diretório, e a expansão de caractere curinga do shell não se importa com o tipo de entidade a que essas entradas se referem.
Praticamente todos os shells com os quais você provavelmente executará (bash, sh, ksh, zsh, csh, tcsh, ...) implementam curingas. Os detalhes podem variar, mas a sintaxe básica de *
que corresponde a zero ou mais caracteres e ?
correspondente a qualquer caractere é razoavelmente consistente.
Para o bash em particular, isso está documentado na seção "Expansão do nome do arquivo" do manual do bash; execute info bash
e pesquise "Expansão de nome de arquivo" ou consulte aqui .
O fato de que isso é feito pelo shell, e não por comandos individuais, tem algumas conseqüências interessantes (e às vezes surpreendentes). A melhor coisa é que o manuseio de curingas é consistente para (quase) todos os comandos all ; se a concha não fizesse isso, inevitavelmente alguns comandos não se incomodariam, e outros o fariam de maneiras sutilmente diferentes, que o autor achava "melhor". (Eu acho que o shell de comando do Windows tem esse problema, mas eu não estou familiarizado o suficiente para comentar mais.)
Por outro lado, é difícil escrever um comando para renomear vários arquivos. Se você escrever:
mv *.log *.log.bak
ele provavelmente falhará, pois *.log.bak
é expandido com base nos arquivos que já existem no diretório atual. Existem comandos que fazem esse tipo de coisa, mas eles precisam usar sua própria sintaxe para especificar como os arquivos devem ser renomeados. Alguns comandos (como find
) podem fazer sua própria expansão de curingas; você tem que citar os argumentos para suprimir a expansão do shell:
find . -name '*.txt' -print
A expansão de curinga do shell é baseada inteiramente na sintaxe do argumento da linha de comando e no conjunto de arquivos existentes. não pode ser afetado pelo significado do comando. Por exemplo, se você quiser mover todos os arquivos .log
para o diretório pai, digite:
mv *.log ..
Se você esquecer o ..
:
mv *.log
e existem exatamente dois arquivos .log
no diretório atual, ele será expandido para:
mv one.log two.log
que renomeará one.log
e clobber two.log
.
EDITAR : E depois de 52 votos positivos, um selo de aceitação e um Guru, talvez eu deva responder a pergunta no título.
A opção -d
ou --directory
para ls
não diz para listar apenas diretórios. Diz-lhe para listar os diretórios como eles mesmos, não o seu conteúdo. Se você der um nome de diretório como um argumento para ls
, por padrão ele irá listar o conteúdo do diretório, já que normalmente é o que você está interessado. A opção -d
diz para lista apenas o diretório em si. Isso pode ser particularmente útil quando combinado com curingas. Se você digitar:
ls -l a*
ls
fornecerá uma lista longa de cada arquivo cujo nome começa com a
e do conteúdo de cada diretório cujo nome começa com a
. Se você quer apenas uma lista dos arquivos e diretórios, uma linha para cada, você pode usar:
ls -ld a*
que é equivalente a:
ls -l -d a*
Lembre-se novamente de que o comando ls
nunca vê o caractere *
.
Quanto a onde isso é documentado, man ls
mostrará a documentação do comando ls
em praticamente qualquer sistema semelhante ao Unix. Na maioria dos sistemas baseados em Linux, o comando ls
faz parte do pacote GNU coreutils; Se você tiver o comando info
, info ls
ou info coreutils ls
deverá fornecer uma documentação mais definitiva e abrangente. Outros sistemas, como o MacOS, podem usar versões diferentes do comando ls
e podem não ter o comando info
; para esses sistemas, use man ls
. E ls --help
mostrará uma mensagem de uso curto relativamente (117 linhas no meu sistema) se você estiver usando a implementação GNU coreutils.
E sim, até os especialistas precisam consultar a documentação agora e depois. Veja também esta piada clássica .