Por que “cat {foo}” não produz foo, mas “cat {foo, bar}” produz?

12

Eu estava tentando concatenar arquivos de texto em subpastas e tentei:

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1}/book.txt > out$var

No entanto, isso não retornou nada. Então, tentei adicionar uma 'subpasta2' inexistente

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1,subfolder2}/book.txt > out$var

E desta vez deu certo, concatenando os arquivos com sucesso. Por que isso acontece?

CDPF
fonte
2
Use em echovez de catpara ver qual linha de comando você obteve. (Ou usar set -xpara depuração.)
Peter Cordes

Respostas:

22

Por definição, a expansão de chaves no GNU Bash requer uma expressão de sequência ou uma série de valores separados por vírgula:

Os padrões a serem expandidos entre colchetes assumem a forma de um preâmbulo opcional, seguido por uma série de cadeias separadas por vírgula ou uma expressão de sequência entre um par de colchetes, seguido de um postscript opcional.

Você pode ler o manual para obter detalhes.

Algumas amostras simples:

echo {subfolder1}
{subfolder1}

echo {subfolder1,subfolder2}
subfolder1 subfolder2

echo subfolder{1}
subfolder{1}

echo subfolder{1..2}
subfolder1 subfolder2
Arthur Hess
fonte
21

{subfolder1}avalia como {subfolder1}, já que não há alternativas. Use em subfolder1vez disso.

Ignacio Vazquez-Abrams
fonte
2
Observe que é diferente de in csh(de onde vem a expansão do suporte) tcshou fish.
Stéphane Chazelas
1

O aparelho somente será expandido se eles tiverem seqüências de caracteres separadas por coma, por exemplo {abc, def} ou intervalo, por exemplo {a..e} especificados entre eles.

No seu caso, você pode simplesmente escrever a subpasta1 sem colocá-la entre chaves, pois não há necessidade disso

cat ./{mainfolder1,mainfolder2,mainfolder3}/subfolder1/book.txt > out$var
Neo_Returns
fonte
Infelizmente, ele se /path/{a,}/filenameexpande para as duas cadeias /path/a/filenamee /path//filename, o que pode ser indesejável.
Kusalananda
graças @Kusalananda para me corrigir, sim festa irá fornecer uma saing aviso "redirecionamento ambígua"
Neo_Returns
Não, você obtém ambiguous redirect se tentar redirecionar para um arquivo fornecido por uma variável não citada que não tem valor, por exemplo echo 'hello' >$idontexist.
Kusalananda
1
... ou se o nome do arquivo no redirecionamento for expandido para várias palavras. Como > *.txtem vários .txtarquivos, ou > $filese $filecontiver espaço em branco. Mas é claro que não há nada ambíguo em dar catvários argumentos
ilkkachu