2009-10-24 15 views
7

Voglio dividere la stringa e costruire l'array. Ho provato il seguente codice:Divisione di una stringa nell'array

myString="first column:second column:third column" 
set -A myArray `echo $myString | awk 'BEGIN{FS=":"}{for (i=1; i<=NF; i++) print $i}'` 
# Following is just to make sure that array is constructed properly 
i=0 
while [ $i -lt ${#myArray[@]} ] 
do 
echo "Element $i:${myArray[$i]}" 
((i=i+1)) 
done 
exit 0 

It produces the following result: 
Element 0:first 
Element 1:column 
Element 2:second 
Element 3:column 
Element 4:third 
Element 5:column 

This is not what I want it to be. When I construct the array, I want that array to contain only three elements. 
Element 0:first column 
Element 1:second column 
Element 2:third column 

Potete per favore avvisare?

+0

Ho trovato la soluzione che è sulle seguenti linee: var = 'word1 # word2 | parola3/word4 | word5.word6 | word7_word8 | word9 word10 | word11 | word12 ' OIFS = $ IFS; IFS = '|' set -A arr $ var IFS = $ OIFS –

+0

puoi rimuovere il ciclo for effettuando una modifica come sotto awk 'BEGIN {FS = ":"} {per (i = 1; i <= NF; i ++) print $ i}. Basta tenerlo come awk 'BEGIN {RS = ":"} {print}' – Vijay

+0

bash sul mio sistema (4.0.33 (5) -release) non ha un'opzione -A per 'set' . Quale versione stai correndo? – outis

risposta

5

se è sicuramente desidera utilizzare le matrici in Bash, si può provare in questo modo

$ myString="first column:second column:third column" 
$ myString="${myString//:/ }" #remove all the colons 
$ echo "${myString}" 
first column second column third column 
$ read -a myArr <<<$myString 
$ echo ${myArr[@]} 
first column second column third column 
$ echo ${myArr[1]} 
column 
$ echo ${myArr[2]} 
second 

in caso contrario, il metodo "migliore" è quello di utilizzare awk interamente

+1

Per mantenere interi valori, si usa: 'IFS =: read -a myArr <<< $ myString' senza rimuovere i due punti. –

2

Sembra che hai già trovato la soluzione, ma si noti che si può fare a meno del tutto awk:

myString="first column:second column:third column" 
OIFS="$IFS" 
IFS=':' 
myArray=($myString) 
IFS=$OIFS 
i=0 
while [ $i -lt ${#myArray[@]} ] 
do 
    echo "Element $i:${myArray[$i]}" 
    ((i=i+1)) 
done 
15

Ecco come vorrei affrontare questo problema: utilizzare la variabile IFS di dire la shell (bash) che si desidera dividere la stringa in a token separati da due punti.

$ cat split.sh 
#!/bin/sh 

# Script to split fields into tokens 

# Here is the string where tokens separated by colons 
s="first column:second column:third column" 

IFS=":"  # Set the field separator 
set $s  # Breaks the string into $1, $2, ... 
i=0 
for item # A for loop by default loop through $1, $2, ... 
do 
    echo "Element $i: $item" 
    ((i++)) 
done 

eseguirlo:

$ ./split.sh 
Element 0: first column 
Element 1: second column 
Element 2: third column 
+1

Funziona solo su una stringa/linea che ha un massimo di 9 colonne. Prova a echeggiare $ 11 e ottieni il valore di $ 1 con "1" aggiunto alla fine. – Dennis

+2

@Dennis - devi usare una notazione diversa per i parametri posizionali oltre 9. '$ {10}, $ {11} ...' http://wiki.bash-hackers.org/scripting/posparams – Cheeso

+0

@Dennis: Ho verificato che il mio codice funziona, anche per le linee con più di 10 colonne. Puoi verificarlo da solo. –

4

noti che salvare e ripristinare IFS come spesso visto in queste soluzioni ha l'effetto collaterale che se IFS non è stato impostato, finisce cambiato ad essere un vuoto stringa che causa strani problemi con la successiva suddivisione.

Ecco la soluzione che ho trovato basata su Anton Olsen's estesa per gestire> 2 valori separati da due punti. Gestisce i valori nella lista che hanno spazi correttamente, non si dividono nello spazio.

colon_list=${1} # colon-separate list to split 
while true ; do 
    part=${colon_list%%:*} # Delete longest substring match from back 
    colon_list=${colon_list#*:} # Delete shortest substring match from front 
    parts[i++]=$part 
    # We are done when there is no more colon 
    if test "$colon_list" = "$part" ; then 
     break 
    fi 
done 
# Show we've split the list 
for part in "${parts[@]}"; do 
    echo $part 
done 
3

Ksh o Bash

#! /bin/sh 
myString="first column:second column:third column" 
IFS=: A=($myString) 

echo ${A[0]} 
echo ${A[1]} 
Problemi correlati