Como posso suprimir o espaço entre argumentos gerados durante a expansão de chaves?


8

Usei o seguinte comando para criar uma lista de URLs que quero testar:

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Infelizmente, os URLs anexados a urls.txtcada um tinham um espaço antes deles (exceto o primeiro, é claro). Entendo por que isso aconteceu, e percebo que poderia simplesmente despejá-lo através de uma sedexpressão, mas gostaria de saber se há uma maneira de suprimi-lo. (Pode parecer bobo e pedante, mas não é diferente da preferência que muitas pessoas sentem por não "abusar de gatos" .)

Tentei citar duas vezes para suprimir a divisão de palavras , mas isso também suprimiu a expansão da cinta, de modo que era impossível.

Tentei alterar o IFS para uma sequência vazia, mas também não funcionou:

IFS='' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Nem alterá-lo para uma nova linha:

IFS='\n' echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}"\n" >> urls.txt

Você está usando bash ou zsh?
Braiam

no momento estou usando o bash (estou no trabalho), mas no meu laptop uso o zsh. Eu esperava que a expansão da cinta funcionasse de forma idêntica nos dois, mas talvez não seja esse o caso.
Iconoclast

Nesse caso, a resposta do Gnouc será a mais compatível com diferentes conchas.
Braiam

A resposta de Richard não seria igualmente compatível? (Ele também tem a vantagem de ser mais simples, portanto, não preciso parar para pensar nos pequenos detalhes da próxima vez que quiser usá-lo.) Por outro lado, a resposta de Gnouc também é excelente. E acho que aprendi mais com a resposta de Glenn Jackson. A resposta de Leiaz parece mais simples e elegante, mas é claro que é apenas zsh.
Iconoclast

Respostas:


8

Você pode armazenar a expansão de chave em uma matriz e, em seguida, produzi-la da maneira que você escolher:

urls=( localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} )

Então

printf "%s\n" "${urls[@]}"

ou

(IFS=$'\n'; echo "${urls[*]}")

O exemplo de eco parece estranho porque:

  1. é executado em um subshell (os parênteses) para não alterar meu valor atual do IFS.
  2. O IFS precisa ser definido em um comando separado:
    • Isso não funciona: IFS=$'\n' echo "${urls[*]}"porque a variável é expandida antes que a nova variável env entre em vigor
    • O IFS precisa ser definido antes de você começar a expandir variáveis.

Além disso, observe a diferença sutil no índice da matriz de desreferenciamento usado:

  • [@] no exemplo printf para expandir a matriz em palavras individuais
  • [*] no exemplo de eco para expandir a matriz em uma única palavra, com elementos separados pelo primeiro caractere do IFS

É uma decisão difícil, mas estou escolhendo esta resposta porque (1) parece (AFAIK) ser o mais próximo do objetivo declarado de suprimir, em vez de apenas remover os espaços, e (2) eu aprendi o máximo disso (a objetivo declarado da minha pergunta).
Iconoclast

16

Use printfbuiltin:

$ printf %s\\n localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}
localhost:8080/reports/promos/130
localhost:8080/reports/promos/130.pdf
localhost:8080/reports/promos/130.xls
localhost:8080/reports/promos/130.xlsx
localhost:8080/reports/promos/130.csv
localhost:8080/reports/promos/130.preload
localhost:8080/reports/promos/130-unburdened
localhost:8080/reports/promos/130-unburdened.pdf
localhost:8080/reports/promos/130-unburdened.xls
localhost:8080/reports/promos/130-unburdened.xlsx
localhost:8080/reports/promos/130-unburdened.csv
localhost:8080/reports/promos/130-unburdened.preload
....

6

Isso está marcado como zsh, então sugiro o zsh embutido print:

print -l localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload}

-l imprime argumentos em linhas separadas.


+1 Obrigado - bom saber! Vou usar isso quando estiver no zsh. Eu marquei isso simplesmente porque eu uso ambos e ambos suportam expansão de chaves. (Eu não sei se qualquer outros fazem, mas eu acho ksh terrivelmente confuso, então eu ficar longe.)
iconoclasta

3

O problema é que a expansão de chaves está adicionando espaço e o eco está adicionando a nova linha. Portanto, usando o princípio de responsabilidade única, lide com a nova linha separadamente.

echo -e localhost:8080/reports/{promos,promo-updates,scandown}/{130,139,142}{,-unburdened,-burdened}{,.pdf,.xls,.xlsx,.csv,.preload} | tr " " "\n"

Eu acho que esta é a abordagem mais simples e mais prático
iconoclasta

Não, a expansão entre chaves não está adicionando espaço, está criando vários argumentos para echo. É isso echoque imprime seus argumentos separados por espaços.
Stéphane Chazelas

Eu acho que o problema ocorre porque echosepara argumentos por espaços e a nova linha é inserida adicionalmente antes de cada espaço, em vez de substituir o espaço (o que seria mais sensato). De memória, xargstem um problema conhecido muito semelhante a esta (especialmente com a -0opção)
SyntaxError
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.