¿Cómo puedo suprimir el espacio entre los argumentos generados durante la expansión de llaves?


8

Usé el siguiente comando para crear una lista de URL que quiero probar:

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

Lamentablemente, las URL adjuntas a urls.txtcada una tenían un espacio antes (excepto la primera, por supuesto). Entiendo por qué sucedió eso, y me doy cuenta de que podría quitarlo con una sedexpresión, pero me gustaría saber si hay una forma de suprimirlo. (Puede parecer tonto y pedante, pero no es diferente de la preferencia que muchas personas sienten por no "abusar de los gatos" ).

Traté de dos comillas para suprimir la división de palabras , pero eso también suprimió la expansión de llaves, por lo que fue imposible.

Intenté cambiar IFS a una cadena vacía, pero tampoco funcionó:

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

Tampoco cambiarlo a una nueva línea:

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

¿Estás usando bash o zsh?
Braiam

en este momento estoy usando bash (estoy en el trabajo) pero en mi propia computadora portátil uso zsh. Esperaba que la expansión de llaves funcionara de manera idéntica en ambos, pero tal vez ese no sea el caso.
iconoclasta

En ese caso, la respuesta de Gnouc será la más compatible con diferentes shells.
Braiam

¿No sería la respuesta de Richard igualmente compatible? (También tiene la ventaja de ser más simple, por lo tanto, no tengo que detenerme y pensar en los fragmentos complicados la próxima vez que quiera usarlo). Por otro lado, la respuesta de Gnouc también es excelente. Y creo que aprendí más de la respuesta de Glenn Jackson. La respuesta de Leiaz parece más simple y elegante, pero por supuesto es solo zsh.
iconoclasta

Respuestas:


8

Puede almacenar la expansión de llaves en una matriz y luego generarla de la manera que elija:

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

Entonces

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

o

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

El ejemplo de eco se ve raro porque:

  1. se ejecuta en una subshell (los paréntesis) para que no altere mi valor actual de IFS.
  2. IFS necesita ser definido en un comando separado:
    • Esto no funciona: IFS=$'\n' echo "${urls[*]}"porque la variable se expande antes de que la nueva variable env entre en vigencia
    • IFS debe establecerse antes de comenzar a expandir las variables.

Además, tenga en cuenta la sutil diferencia en el índice de matriz de referencia utilizado:

  • [@] en el ejemplo printf para expandir la matriz en palabras individuales
  • [*] en el ejemplo echo para expandir la matriz en una sola palabra, con elementos separados por el primer carácter de IFS

Es una decisión difícil, pero elijo esta respuesta porque (1) parece (AFAIK) ser la más cercana al objetivo declarado de suprimir en lugar de simplemente eliminar los espacios, y (2) aprendí más de ella (a objetivo declarado de mi pregunta).
iconoclasta

16

Use printfincorporado:

$ 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

Esto está etiquetado como zsh, por lo que sugiero el zsh incorporado print:

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

-l imprime argumentos en líneas separadas.


+1 Gracias, ¡es bueno saberlo! Lo usaré cuando esté en zsh. Lo etiqueté simplemente porque uso ambos y ambos admiten la expansión de llaves. (No sé si otros lo hacen, pero encuentro ksh terriblemente confuso, así que me mantengo alejado)
Iconoclasta

3

El problema es que la expansión de la llave está agregando el espacio, y echo está agregando la nueva línea. Entonces, utilizando el principio de responsabilidad única, maneje la nueva línea por separado.

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

Creo que este es el enfoque más simple y práctico
iconoclasta

No, la expansión de llaves no agrega espacio, sino que crea varios argumentos echo. Eso es lo echoque imprime sus argumentos separados por espacios.
Stéphane Chazelas

Supongo que el problema ocurre porque echosepara los argumentos por espacios y la nueva línea se inserta adicionalmente antes de cada espacio en lugar de reemplazar el espacio (lo que sería más sensato). De memoria, xargstiene un problema conocido muy similar a este (especialmente con la -0opción)
syntaxerror
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.