GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo dividir una cadena con comillas (como argumentos de comando) en bash?

La solución más simple es hacer una matriz de los argumentos entre comillas que luego puede repetir si lo desea o pasar directamente a un comando.

eval "array=($string)"

for arg in "${array[@]}"; do echo "$arg"; done   

PD. Comente si encuentra una forma más sencilla sin eval .

Editar:

Sobre la base de la respuesta de @Hubbitus, tenemos una versión completamente desinfectada y citada correctamente. Nota:esto es excesivo y en realidad dejará barras diagonales inversas adicionales en las secciones con comillas simples o dobles que preceden a la mayoría de los signos de puntuación, pero es invulnerable a los ataques.

declare -a "array=($( echo "$string" | sed 's/[][`[email protected]#$%^&*():;<>.,?/\|{}=+-]/\\&/g' ))"

Dejo al lector interesado que modifique como mejor le parezca http://ideone.com/FUTHhj


Cuando vi la respuesta de David Postill, pensé "debe haber una solución más simple". Después de algunos experimentos encontré los siguientes trabajos:-

string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
echo $string
eval 'for word in '$string'; do echo $word; done'

Esto funciona porque eval expande la línea (eliminando las comillas y expandiendo string ) antes de ejecutar la línea resultante (que es la respuesta en línea):

for word in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $word; done

Una alternativa que se expande a la misma línea es:

eval "for word in $string; do echo \$word; done"

Aquí string se expande entre comillas dobles, pero el $ debe escaparse para que word no se expande antes de que se ejecute la línea (en la otra forma, el uso de comillas simples tiene el mismo efecto). Los resultados son:-

[~/]$ string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
[~/]$ echo $string
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
[~/]$ eval 'for word in '$string'; do echo $word; done'
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo
[~/]$ eval "for word in $string; do echo \$word; done"
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

¿Cómo hago eso?

$ for l in "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"; do echo $l; done
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

¿Qué hago si mi cadena está en un bash? variable?

El enfoque simple de usar el bash el tokenizador de cadenas no funcionará, ya que se divide en todos los espacios, no solo en los que están fuera de las comillas:

[email protected] /f/test
$ cat ./test.sh
#! /bin/bash
string='"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"'
for word in $string; do echo "$word"; done

[email protected] /f/test
$ ./test.sh
"aString
that
may
haveSpaces
IN
IT"
bar
foo
"bamboo"
"bam
boo"

Para evitar esto, el siguiente script de shell (splitstring.sh) muestra un enfoque:

#! /bin/bash 
string=$(cat <<'EOF'
"aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo" 
EOF
)
echo Source String: "$string"
results=()
result=''
inside=''
for (( i=0 ; i<${#string} ; i++ )) ; do
    char=${string:i:1}
    if [[ $inside ]] ; then
        if [[ $char == \\ ]] ; then
            if [[ $inside=='"' && ${string:i+1:1} == '"' ]] ; then
                let i++
                char=$inside
            fi
        elif [[ $char == $inside ]] ; then
            inside=''
        fi
    else
        if [[ $char == ["'"'"'] ]] ; then
            inside=$char
        elif [[ $char == ' ' ]] ; then
            char=''
            results+=("$result")
            result=''
        fi
    fi
    result+=$char
done
if [[ $inside ]] ; then
    echo Error parsing "$result"
    exit 1
fi

echo "Output strings:"
for r in "${results[@]}" ; do
    echo "$r" | sed "s/\"//g"
done

Salida:

$ ./splitstring.sh
Source String: "aString that may haveSpaces IN IT" bar foo "bamboo" "bam boo"
Output strings:
aString that may haveSpaces IN IT
bar
foo
bamboo
bam boo

Fuente:Respuesta de StackOverflow Dividir una cadena solo por espacios que están fuera de las comillas de choroba. Se ha modificado el guión para que coincida con los requisitos de la pregunta.


Linux
  1. Cómo dividir una cadena en Bash Script

  2. Compruebe cuánto tarda en ejecutarse un script de Bash con el comando de tiempo

  3. Cómo crear un pico de CPU con un comando bash

  4. ¿Cómo ordenar archivos en carpetas por tipo de archivo en bash (con el comando 'archivo')?

  5. ¿Cómo ejecutar el comando bash con privilegios sudo en Java?

Comando Echo en Linux (con ejemplos)

Comando Echo en Linux con ejemplos

Comando Bash Echo explicado con ejemplos en Linux

Cómo usar el comando echo en Bash Scripts en Linux

Cómo encontrar archivos con docenas de criterios con el comando Bash Find

Comando dividido de Linux con ejemplos