Comment diviser la sortie et la stocker dans un tableau?

9

Voici la sortie:

3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720

J'ai essayé avec 2 scénarios:

  1. Stockage dans un tableau

      @arr=split(',',$stats);
      echo "statistics: $stats"
    
  2. Stockage dans une variable

     echo $stats | cut -d ',' -f | read s1
     echo $s1
    

Mais aucun des deux scénarios ne fonctionne.

Maheshwari
la source
awk '{ split("3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720 ",arr,","); print arr[1]; }' OU echo "3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, h.264, 1029.1, 31, 31, 0,0,0.000000,31,31,0,0,0.000000,7,0,0,0.000000,30,1280 720,10,0,0,0.000000,30,1280 720" | awk '{ split($0,arr,","); print arr[1]; }' Cela devrait fonctionner.

Réponses:

9

Vous pouvez utiliser quelque chose comme ça, pour une seule ligne d'entrée:

IFS="," read -ra arr <<< "$foo"

Démo:

$ cat t.sh 
foo="3,aac-lc, 93.8, aaclc, 77.3, h.264, 1024.6, ..." # snipped

IFS="," read -ra arr <<< "$foo"
echo ${#arr[@]}
echo ${arr[0]}
echo ${arr[30]}
$ ./t.sh 
31
3
1280 720

Crédits: Split string basé sur le délimiteur dans bash? réponse de Johannes Schaub . Vérifiez également les autres réponses.

Tapis
la source
2

Votre premier extrait de code n'a rien à voir avec la syntaxe du shell. C'est une syntaxe Perl correcte.
Votre deuxième extrait de code ne fonctionne pas cutcorrectement; Je ne sais pas ce que tu voulais.

Le shell a une construction de fractionnement de chaîne intégrée: lorsque vous écrivez $somevarsans guillemets, le shell recherche d'abord la valeur de la variable somevar, puis divise cette valeur en mots séparés sur les caractères spécifiés par IFS, et interprète enfin chaque mot comme un glob modèle (fichier joker). Vous pouvez donc diviser une chaîne en définissant IFSle caractère séparateur et en désactivant temporairement la globalisation.

set -f; IFS=,
arr=($stats)
set +f; unset IFS

Notez que si un champ contient un espace, l'élément de tableau conservera cet espace. Si vous souhaitez séparer tous les espaces ainsi que les virgules, définissez IFS=', '. Notez que ce IFSn'est pas une chaîne à diviser mais un ensemble de caractères à diviser; un espace ou une virgule constituera un séparateur. En outre, il existe des règles spéciales pour les espaces blancs: toute séquence de zéro ou plusieurs espaces suivie d'une virgule suivie de zéro ou plusieurs espaces constituera un séparateur, et toute séquence d'un ou plusieurs espaces constituera également un séparateur.

Si vous souhaitez uniquement supprimer les espaces au début ou à la fin d'un champ, vous devrez le faire élément par élément.

shopt -s extglob
for ((i=0; i<${#arr[@]}; i++)); do
  arr[i]=${arr[i]#+( )}   # strip one or more spaces at the beginning
  arr[i]=${arr[i]%+( )}   # strip one or more spaces at the end
done
Gilles 'SO- arrête d'être méchant'
la source
2
$ set -f  # turn off globbing, so as not to expand wildcards
$ arr=($(echo "$stats" | sed 's/,/ /g'))
$ echo ${arr[1]}
aac-lc
Kyle Jones
la source
1
Notez que cela traitera les espaces comme des séparateurs ainsi que des virgules.
Gilles 'SO- arrête d'être méchant'