Qual é a diferença entre ls [13] e ls {1,3}?

Qual é a diferença entre ls [13] e ls {1,3}?

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].txte 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}, substitui xe ypor qualquer valor alfabético ou numérico.

    Na primeira forma, {x..y}será expandido para todos os valores de xaté y, inclusive. Por exemplo, {2..5}será expandido para 2, 3, 4, 5.

    Na segunda forma explícita, {x,y}será expandido apenas para x, y. Por exemplo, {2,5}será expandido para 2e 5.

    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].txtfor corresponderá a um arquivo chamado 2.txtou 5.txtno diretório atual, enquanto for [245].txtcorresponderá a qualquer arquivo chamado 2.txtor 4.txtou 5.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 chamado 2.txtou 3.txtou 4.txtou 5.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( shno Ubuntu) não tem isso. Ele foi emprestado cshe 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}.txtse expande para inv1.txte inv5.txtindependentemente de quais arquivos estão realmente em seu sistema de arquivos. Isso éexpansão de cinta.

informação relacionada