GNU/Linux >> Linux Esercitazione >  >> Linux

Come dividere una stringa con virgolette (come argomenti di comando) in bash?

La soluzione più semplice consiste nell'utilizzare la creazione di un array degli argomenti tra virgolette che puoi quindi ripetere se lo desideri o passare direttamente a un comando.

eval "array=($string)"

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

p.s. Commenta se trovi un modo più semplice senza eval .

Modifica:

Basandoci sulla risposta di @Hubbitus, abbiamo una versione completamente ripulita e opportunamente citata. Nota:questo è eccessivo e in realtà lascerà barre rovesciate aggiuntive nelle sezioni con virgolette doppie o singole che precedono la maggior parte della punteggiatura, ma è invulnerabile agli attacchi.

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

Lascio al lettore interessato di modificare come meglio crede http://ideone.com/FUTHhj


Quando ho visto la risposta di David Postill, ho pensato "ci deve essere una soluzione più semplice". Dopo alcuni esperimenti ho trovato i seguenti lavori:-

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

Funziona perché eval espande la riga (rimuovendo le virgolette ed espandendo string ) prima di eseguire la riga risultante (che è la risposta in linea):

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

Un'alternativa che si espande alla stessa riga è:

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

Qui string è espanso tra virgolette doppie, ma il $ deve essere preceduto dall'escape in modo che word in non espanso prima dell'esecuzione della riga (nell'altra forma l'uso delle virgolette singole ha lo stesso effetto). I risultati sono:-

[~/]$ 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

Come posso farlo?

$ 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

Cosa devo fare se la mia stringa è in un bash variabile?

Il semplice approccio all'utilizzo del bash string tokenizer non funzionerà, poiché si divide in ogni spazio, non solo in quelli al di fuori delle virgolette:

[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"

Per aggirare questo problema, il seguente script di shell (splitstring.sh) mostra un approccio:

#! /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

Uscita:

$ ./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

Fonte:risposta StackOverflow Dividi una stringa solo per spazi che sono al di fuori delle virgolette di choroba. Lo script è stato ottimizzato per soddisfare i requisiti della domanda.


Linux
  1. Come suddividere un file come Dividi in Stdout per eseguire il piping su un comando?

  2. Come dividere una stringa nello script Bash

  3. Come scrivere più stringhe di righe usando Bash con variabili?

  4. Come eseguire il comando bash con privilegi sudo in Java?

  5. bash:come passare argomenti della riga di comando contenenti caratteri speciali

Comando Echo in Linux (con esempi)

Echo Command in Linux con esempi

Comando Bash Echo spiegato con esempi in Linux

Come utilizzare il comando echo negli script Bash in Linux

Come trovare file con dozzine di criteri con il comando Trova Bash

Comando diviso Linux con esempi