2010-06-23 7 views
16
function foo() { 
[email protected] 
echo $A 
} 

foo bla "hello ppl" 

me gustaría que la salida sea:
"bla" hola "PPL"Bash: concatenar todos los argumentos y se envuelven con comillas dobles

¿Qué tengo que hacer en lugar de los puntos suspensivos?

+0

¿Qué estás tratando de lograr?¿La salida de 'foo' se usa como entrada a algo o solo quieres el texto sin formato? – msw

+0

Se supone que debe usarse como entrada para otro comando (correo en este caso). – rui

+4

@rubim: entonces creo que lo estás haciendo mucho más difícil de lo necesario. 'mail" $ @ "' daría los resultados sin el paso de des-analizar/re-analizar. Si '" $ @ "' no está en el estado correcto, muestra lo que tienes. – msw

Respuesta

3

puede utilizar "$ @" tratar a cada parámetro como, también, un parámetro separado, y luego un bucle sobre cada parámetro:

function foo() { 
for i in "[email protected]" 
do 
    echo -n \"$i\"" " 
done 
echo 
} 

foo bla "hello ppl" 
+1

+1 ¡Esta solución funciona! Soy flojo, así que suelo soltar la parte 'in' $ @ '' y solo uso 'for i' –

+0

Olvidé mencionar esto en la pregunta, pero tenía la intención de hacerlo sin usar un bucle. Estaba buscando alguna expansión mágica de bash o algo así. – rui

3

ninjalj tenía la idea correcta, pero el uso de comillas era extraño , en parte porque lo que el OP está pidiendo no es realmente el mejor formato de salida para muchas tareas de shell. En realidad, no puedo imaginar lo que la tarea prevista es, pero:

function quote_args { 
    for i ; do 
     echo \""$i"\" 
    done 
} 

pone a sus argumentos citado uno por línea, que es generalmente la mejor manera de alimentar a otros programas. Lo que se obtiene de salida en una forma que no pidió:

$ quote_args this is\ a "test really" 
"this" 
"is a" 
"test really" 

pero se puede convertir fácilmente y esto es el idioma que más invocaciones de concha preferirían:

$ echo `quote_args this is\ a "test really"` 
"this" "is a" "test really" 

pero a menos que sea pasando por otro pase eval, las cotizaciones adicionales probablemente arruinarán las cosas. Es decir, ls "is a file" enumerará el archivo is a file mientras

$ ls `quote_args is\ a\ file` 

a tratar de enumerar "is, a y file" la que es probable que no desee.

2

Sin bucle requerido:

foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; } 

Ahorro IFS no es necesario en este ejemplo sencillo, especialmente justo antes de la restauración que se cierra la función, debido al hecho de que se utiliza local. Sin embargo, lo incluí en caso de que otras cosas entren en la función que podría afectar un IFS modificado.

Ejemplo ejecute:

$ foo a bcd "efg hij" k "lll mmm nnn " ooo " ppp qqq " rrr\ sss 
"a" "bcd" "efg hij" "k" "lll mmm nnn " "ooo" " ppp qqq " "rrr sss" 
6

Uso sustitución de parámetros para agregar "como prefijo y sufijo:

function foo() { 
    A=("${@/#/\"}") 
    A=("${A[@]/%/\"}") 
    echo -e "${A[@]}" 
} 

foo bla "hello ppl" kkk 'ss ss' 

salida

"bla" "hello ppl" "kkk" "ss ss" 
21

@msw tiene la idea correcta (en el comentarios sobre la pregunta).Sin embargo, otra idea para imprimir argumentos con citas: utilizar la iteración implícita de printf:

foo() { printf '"%s" ' "[email protected]"; echo ""; } 

foo bla "hello ppl" 
# => "bla" "hello ppl" 
+3

Ding! Tú ganas el gran premio. ¿Oso de peluche gigante o banco de monedas de cerveza de cuatro pies? –

+0

¿Por qué agregó echo ""; ¿al final? ¿No es innecesario? – EminezArtus

+0

Entonces la salida terminaría con una nueva línea. Para que se vea bien y no estropee su mensaje. Me doy cuenta de que es innecesario cuando se lo llama con una sustitución de comando –

1

La única solución en este tiempo que respeta las barras invertidas y citas dentro del argumento:

$ concatenate() { printf "%q"" " "[email protected]"; echo ""; } 
$ concatenate arg1 "arg2" "weird arg3\\\\\\bbut\" legal!" 
arg1 arg2 weird\ arg3\\\\\\bbut\"\ legal\! 

Aviso del " % q "" "

% q argumento es impreso en un formato que puede ser reutilizado como ella ll entrada , escapando caracteres no imprimibles con la sintaxis POSIX $ '' propuesta por .

caracteres especiales (\, \b de retroceso, ...) serán de hecho ser interpretados por el programa receptor, incluso si no está representada interpretado a la salida del terminal. prueba

Repasemos:

# display.sh: Basic script to display the first 3 arguments passed 
echo -e '#!/bin/bash'"\n"'echo -e "\$1=""$1"; echo -e "\$2=""$2"; echo -e "\$3=""$3"; sleep 2;' > display.sh 
sudo chmod 755 display.sh 

# Function to concatenate arguments as $ARGS 
# and "evalutate" the command display.sh $ARGS 
test_bash() { ARGS=$(concatenate "[email protected]"); bash -c "./display.sh ""$ARGS"; } 

# Test: Output is identical whatever the special characters 
./display.sh arg1 arg2 arg3 
test_bash arg1 arg2 arg3 

Más pruebas complican:

./display.sh arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-" 
test_bash arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-" 

En display.sh, estamos utilizando echo -e en lugar de sólo echoprintf o con el fin de interpretar los caracteres especiales. Esto es solo representativo si su programa llamado los interpreta.

-e permitir la interpretación de la barra invertida se escapa

Si -e es, en efecto, las siguientes secuencias son reconocidas:

  • \ backslash
  • \ a alerta (BEL)
  • \ b retroceso
  • Etc.

NB: \b es el carácter de retroceso, por lo que borra Y en el ejemplo.

Tenga en cuenta que este ejemplo no es para ser reproducida en código real:

Gracias a la respuesta aceptada y Danny Hong answer en "Cómo escapar comillas dobles dentro de una cita doble?"

Cuestiones relacionadas