2009-10-24 10 views
7

Quiero dividir la cadena y construir la matriz. Probé el siguiente código:División de cadena en matriz

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 

¿Puede por favor asesorar?

+0

he encontrado la solución que se encuentra en las siguientes líneas: var = '# palabra1 palabra2 | word3/WORD4 | word5.word6 | word7_word8 | WORD9 word10 | word11 | word12 ' OIFS = $ IFS; IFS = '|' establecer -A arr $ var IFS = $ OIFS –

+0

puede eliminar el bucle for haciendo un cambio como el siguiente awk 'BEGIN {FS = ":"} {for (i = 1; i <= NF; i ++) print $ i} .just keep it as awk 'BEGIN {RS = ":"} {print}' – Vijay

+0

bash en mi sistema (4.0.33 (5) -release) no tiene una -A opción para 'set' . ¿Qué versión está usando? – outis

Respuesta

5

si que debe de utilizar matrices en Bash, puede tratar de esta manera

$ 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 

de lo contrario, el método de "mejor" es usar awk completo

+1

Para mantener valores enteros, se usaría: 'IFS =: leer -a myArr <<< $ myString' sin eliminar dos puntos. –

2

Parece que ya ha encontrado el solución, pero tenga en cuenta que puede acabar con awk completo:

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

Aquí es cómo iba a abordar este problema: utilizar la variable IFS para contar la cáscara (bash) que desea dividir la cadena de a tokens separados por colon

$ 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 

Run que:

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

Esto solo funciona en una cadena/línea que tiene un máximo de 9 columnas. Intenta hacer eco de $ 11 y obtienes el valor de $ 1 con '1' agregado al final. – Dennis

+2

@Dennis: necesita usar una notación diferente para los parámetros posicionales más allá de 9. '$ {10}, $ {11} ...' http://wiki.bash-hackers.org/scripting/posparams – Cheeso

+0

@Dennis: He verificado que mi código funciona, incluso para líneas con más de 10 columnas. Usted puede verificarlo usted mismo. –

4

Tenga en cuenta que guardar y restaurar IFS ya que a menudo visto en estas soluciones tiene el efecto secundario de que si IFS no se ha establecido, termina cambiado de ser un vacío cadena que causa problemas extraños con la división posterior.

Aquí está la solución que surgió basada en Anton Olsen's extendida para manejar> 2 valores separados por dos puntos. Maneja valores en la lista que tienen espacios correctamente, sin dividir en el espacio.

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]} 
Cuestiones relacionadas