2017-08-31 2 views
1

J'utilise IFS=', ' pour diviser une chaîne de texte délimité par des virgules dans un tableau. Le problème est que parfois l'un des éléments délimités par des virgules contient un espace suivant un :. Le tableau résultant contient cet élément en tant que deux éléments de tableau séparés. Est-il possible de définir IFS à seulement diviser ', ' et ignorer un élément délimité par des virgules qui contient ': ' (ou tout autre caractère d'ailleurs)?Bash: initialise IFS à Space après un caractère spécifique uniquement?

Voir la chaîne délimitée par des virgules retournée par la première commande ci-dessous, notez que le deuxième élément a le :. Voir le MarkerNames[1] and MarkerNames[2] pour voir la division indésirable dans la deuxième commande ci-dessous.

$ exiftool -s3 -TracksMarkersName audioFile.wav 
Marker1, Tempo: 120.0, Silence, Marker2, Silence.1, Marker3, Silence.2, Marker4, Silence.3, Marker5 

$ IFS=', ' read -r -a MarkerNames <<< $(exiftool -s3 -TracksMarkersName audioFile.wav) 
$ declare -p MarkerNames 
declare -a MarkerNames='([0]="Marker1" [1]="Tempo:" [2]="120.0" [3]="Silence" [4]="Marker2" [5]="Silence.1" [6]="Marker3" [7]="Silence.2" [8]="Marker4" [9]="Silence.3" [10]="Marker5")' 
+0

Pouvez-vous poster un [mcve]? – tripleee

+0

Ajouté. Merci @tripleee. –

Répondre

2

IFS contient une énumération des caractères qui chaque peut être un séparateur de champ. Donc, ", " dit "n'importe quelle série d'espaces ou de virgules sépare mes champs". La solution de contournement la plus simple serait, je pense, de prétraiter la sortie afin que vous obteniez les pauses où vous le souhaitez.

IFS='~' MarkerNames=($(exiftool -s3 -TracksMarkersName audioFile.wav | sed 's/, /~/g')) 

Bien sûr, vous oblige à trouver une autre valeur IFS qui ne se produit pas dans vos données. Si Bash 4+ est disponible, utilisez peut-être une nouvelle ligne et readarray.

+0

Cela a fonctionné parfaitement, merci! –

+0

Notez que ceci définit globalement "IFS" *, et pas seulement pendant la durée du découpage des mots pour remplir 'MarkerNames'. – chepner

+0

@chepner Ouch, vraiment? TIL. Peut-être mettre cela dans une fonction avec 'IFS local 'alors. – tripleee

0

Vous pouvez diviser les virgules et les enlever les grands espaces/arrière après:

IFS=',' read -r -a MarkerNames <<< $(exiftool -s3 -TracksMarkersName audioFile.wav) 
shopt -s extglob       # Needed for extended glob 
MarkerNames=("${MarkerNames[@]/#*()}") # Remove leading spaces 
MarkerNames=("${MarkerNames[@]/%*()}") # Remove trailing spaces