2011-10-11 19 views
31

me gustaría integrar un comando largo como este en un script bash:¿Cómo rompo un literal de cadena extremadamente largo en bash?

mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/that/i/would/like/to/be/able/to/break/up/if/possible \ 
    --otherflag \ 
    --anotherflag 

con el nombre de archivo largo roto.

que podía hacer esto:

# Insufficiently pretty 
mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/\ 
that/i/would/like/to/be/able/to/break/\ 
up/if/possible \ 
    --otherflag \ 
    --anotherflag \ 

pero se rompe el flujo. Me como para ser capaz de escribir esto:

# Doesn't work 
mycommand \ 
    --server myserver \ 
    --filename extremely/long/file/name/\ 
     that/i/would/like/to/be/able/to/break/\ 
     up/if/possible \ 
    --otherflag \ 
    --anotherflag 

pero eso no funciona porque se rompe la cadena literal.

¿Hay alguna manera de decirle a bash que rompa una cadena literal pero ignore los espacios iniciales?

Respuesta

36

Puede utilizar una variable:

file=extremely/long/file/name 
file+=/that/i/would/like/to/be/able/to/break 
file+=/up/if/possible 

mycommand\ 
    --server myserver\ 
    --filename $file\ 
    --flag flag 
+6

Buena idea. Puedes hacerlo más limpio, usando el operador '+ =' en lugar de 'file = $ {file}/...' – Chriszuma

+5

+1: este es el enfoque menos ofuscado en mi opinión. La intención es clara. –

+0

@Chriszuma Sí, olvidé que bash permitió el operador '+ ='. Edité mi respuesta. – WilQu

36

Es un poco de un corte , pero esto funciona:

mycommand \ 
    --server myserver \ 
    --filename "extremely/long/file/name/"` 
       `"that/i/would/like/to/be/able/to/break/"` 
       `"up/if/possible" \ 
    --otherflag \ 
    --anotherflag 

Bash concatena cadenas literales que están adyacentes, así que tome ventaja de eso. Por ejemplo, echo "hi" "there" imprime hi there mientras que echo "hi""there" imprime hithere.

También se aprovecha del operador de backtick, y el hecho de que un montón de espacios se evalúa a nada.

+2

Puede poner la apertura '\' 'al final de la línea anterior, en lugar de la' \ 'línea de continuación ... mantiene el borde izquierdo limpio –

+0

Buena llamada, no pensó en eso. Debidamente editado. – Chriszuma

1

Básicamente, no hay nada integrado en bash para hacer esto.
Un contenedor suele ser más problemático de lo que vale, pero dicho esto, podría probar un alias o un funciton, por ejemplo. j

j(){sed -e ':a;$!N;s/ *\n *//g;ta' <<<"$1"} 

echo "$(j "3 spaces 
      /hello 
      /world 
      /this 
      /is 
      /a 
      /long 
      /path 
      ")" 

# 3 spaces/hello/world/this/is/a/long/path 
3

que definen una función strcat corto en la parte superior de mi escritura del golpe y utilizar una invocación en línea para dividir las cosas. A veces prefiero utilizar una variable separada porque puedo definir el literal largo en línea con la invocación del comando.

function strcat() { 
    local IFS="" 
    echo -n "$*" 
} 

mycommand \ 
    --server myserver \ 
    --filename "$(strcat \ 
     extremely/long/file/name/ \ 
     that/i/would/like/to/be/able/to/break/ \ 
     up/if/possible)" \ 
    --otherflag \ 
    --anotherflag \ 

También me gusta este enfoque para cuando tenga que entrar en un largo CSV de valores como parámetro indicador porque puedo utilizarlo para evitar tener que escribir la coma entre los valores:

function strjoin() { 
    local IFS="$1" 
    shift 
    echo -n "$*" 
} 

csv_args=(
    foo=hello 
    bar=world 
    "this=arg has spaces in it" 
) 
mycommand \ 
    --server myserver \ 
    --csv_args "$(strjoin , "${csv_args[@]}")" \ 
    --otherflag \ 
    --anotherflag \ 

lo que equivale a

mycommand \ 
    --server myserver \ 
    --csv_args "foo=hello,bar=world,this=arg has spaces in it" \ 
    --otherflag \ 
    --anotherflag \ 
1

también se puede utilizar una matriz variable de

file=(extremely/long/file/name 
    /that/i/would/like/to/be/able/to/break 
    /up/if/possible) 
IFS='' 

echo mycommand\ 
    --server myserver\ 
    --filename "${file[*]}"\ 
    --flag flag 
Cuestiones relacionadas