![Qual é a diferença entre ls [13] e ls {1,3}?](https://rvso.com/image/885982/Qual%20%C3%A9%20a%20diferen%C3%A7a%20entre%20ls%20%5B13%5D%20e%20ls%20%7B1%2C3%7D%3F.png)
Criei três arquivos em meu diretório usando o comando touch inv{1..3}.txt
. Agora usei dois comandos e a saída deles é praticamente a mesma. Esses dois comandos são ls inv[13].txt
e ls {1,3}.txt
.
Então, como esses dois são diferentes? Qual a diferença entre colchetes e colchetes? Além disso, eu estava pesquisando "linux [..]" no Google, mas não consegui encontrar nada, então poderia saber como essas coisas são chamadas na terminologia do Linux?
Obrigado
Responder1
{}
é chamado de expansão de chave. Possui duas formas:{x..y}
e{x,y}
, substituix
ey
por qualquer valor alfabético ou numérico.Na primeira forma,
{x..y}
será expandido para todos os valores dex
atéy
, inclusive. Por exemplo,{2..5}
será expandido para2
,3
,4
,5
.Na segunda forma explícita,
{x,y}
será expandido apenas parax
,y
. Por exemplo,{2,5}
será expandido para2
e5
.Se nenhuma expansão for possível, o padrão é tratado literalmente, por exemplo, em
{a..3}
.É importante observar que a expansão das chaves será feita (se possível) independentemente de qualquer correspondência de arquivo, durante a criação/correspondência de arquivo.
[]
é conhecido como padrão de expansão (ou globbing) de nome de caminho. Ao contrário da expansão de chaves, você só pode usá-la ao combinar nomes de arquivos; ela será tratada literalmente se você usá-la ao criar arquivos.Possui duas formas:
[xyz...]
e[x-y]
.Na primeira forma, ele corresponderá a qualquer caractere dentro dos colchetes separadamente, ou seja, cada caractere é tratado individualmente. Portanto,
[25].txt
for corresponderá a um arquivo chamado2.txt
ou5.txt
no diretório atual, enquanto for[245].txt
corresponderá a qualquer arquivo chamado2.txt
or4.txt
ou5.txt
.Na segunda forma, uma expansão de intervalo é feita primeiro antes da correspondência individual, se possível tratada literalmente. Então, para
[2-5]. txt
, ele corresponderá a qualquer arquivo chamado2.txt
ou3.txt
ou4.txt
ou5.txt
. Se o intervalo não puder ser expandido, ele será tratado literalmente, por exemplo, no caso de[a-3].txt
.
Uma importante diferença comportamental entre os dois é quando há mais padrões para combinar, enquanto menos são realmente correspondidos. Como a expansão das chaves é feita de qualquer maneira, ele mostrará um erro de que determinados arquivos não existem, enquanto a expansão do nome do caminho corresponderá ao que for possível, sem qualquer erro para o resto:
$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt 2.txt 3.txt
$ ls [1-4].txt
1.txt 2.txt 3.txt
Nota de portabilidade:
O []
operador de expansão do nome do caminho é definido pelo POSIX, portanto portátil entre Bourne Shell e derivados.
A expansão de chaves, {}
, não é definida pelo POSIX, portanto, não é portátil entre todos os shells. Por exemplo, dash
( sh
no Ubuntu) não tem isso. Ele foi emprestado csh
e funcionará apenas em determinados shells, por exemplo bash
, zsh
, ksh93
, , fish
. Certifique-se de que o shell que você está usando suporta isso antes de implementar.
Exemplo:
$ touch {1..3}.txt
$ ls {1..3}.txt
1.txt 2.txt 3.txt
$ ls {1,2,3}.txt
1.txt 2.txt 3.txt
$ ls {1..4}.txt
ls: cannot access 4.txt: No such file or directory
1.txt 2.txt 3.txt
$ ls {a..3}.txt
ls: cannot access {a..3}.txt: No such file or directory
$ ls [123].txt
1.txt 2.txt 3.txt
$ ls [1-3].txt
1.txt 2.txt 3.txt
$ ls [1-4].txt
1.txt 2.txt 3.txt
$ ls [a-3].txt
ls: cannot access [a-3].txt: No such file or directory
Responder2
A principal diferença entre as duas formas é ilustrada aqui:
$ ls inv[15].txt
inv1.txt
$ ls inv{1,5}.txt
ls: cannot access 'inv5.txt': No such file or directory
inv1.txt
inv[15].txt
é um glob e expandirá a lista de arquivos correspondentes em seu sistema de arquivos. Isso éexpansão do nome do caminho.
inv{1,5}.txt
se expande para inv1.txt
e inv5.txt
independentemente de quais arquivos estão realmente em seu sistema de arquivos. Isso éexpansão de cinta.