Création d'un tableau avec IFS défini sur une valeur différente

J'essaie de build un tableau et d'écrire dans un file dans ce format, c'est-à-dire que le contenu du file devrait être quelque chose comme ça

hero_pairscore=( askdjfh sdf,sdlkfj lksf,dfgdf,dsflkgj,asdlkf ....) 

Où les éléments sont séparés par une comma . J'ai écrit le code suivant pour cela.

 #!/bin/bash #set -x hero_pairscore=() while read line do $( IFS=",";hero_pairscore+=( "$line" ) done < true_pairscore.txt echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt 

Mais le file résultant ne contient que ce hero_pairscore=( ) . Quel est le problème avec mon code et comment puis-je le corriger pour donner la sortie désirée?

Pour faire ce que je pense que vous essayez de faire, qui est lu chaque champ séparé par des virgules dans true_pairscore.txt dans une variable de tableau, il n'y a pas beaucoup de mal avec votre code. Le $( au début de la ligne IFS est évidemment erroné et entraînerait une erreur du script (c'est peut-être pour cette raison que vous n'obtenez aucune sortie). Sinon, le correctif principal serait simplement de supprimer cotes autour de $line puisque vous voulez que bash fasse un partage de mots autour d' IFS (en général c'est ce que vous les utilisez pour éviter):

 #!/bin/bash set -o noglob OIFS=$IFS IFS="," hero_pairscore=() while IFS= read -r line do hero_pairscore+=( $line ) done < true_pairscore.txt echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt set +o noglob IFS=$OIFS 

Cependant, voici une astuce pour faire ce qui précède en seulement deux lignes:

 IFS=$',\n' read -ra hero_pairscore -d '' <true_pairscore.txt echo "hero_pairscore=( ${hero_pairscore[@]} )" > embed.txt 

Mettre à jour

Si le file embed.txt doit provenir d'un autre shell bash , vous souhaiterez probablement citer chaque élément du tableau hero_pairscore écrit. Pour ce faire, remplacez l' echo "hero_pairscore=( ${hero_pairscore[@]} )" par:

 echo "hero_pairscore=( $(printf '"%s" ' "${hero_pairscore[@]}") )" 

Tout ce que vous devez faire ici est la suivante:

  1. Définissez la variable. Nous allons utiliser ceci:

     var="kijhg, fbjhku,,,ioy fbjfr, kjmyhg" 
  2. Définissez le $IFS et empêchez l'extension de nom de file:

     IFS=, ; set -f 
  3. set shell $@ array pour la sortie.

     set -- $var 
  4. Réinitialiser le shell parent $IFS et les parameters du shell:

     unset IFS ; set +f 
  5. Hourra! Il conserve même plusieurs répétitions et espaces et tout!

     printf %s\\n "$@" 

    SORTIE

     kijhg fbjhku ioy fbjfr kjmyhg 

Quoi qu'il en soit, prenez ma parole pour cela. Chaque caractère qui n'est pas un , est préservé.

TRANSFORMER

Je recommand particulièrement d'utiliser le véritable shell shell par opposition au tableau bash car vous pouvez instantanément transformer son splitter.

 printf %s "$*" #OUTPUT# kijhg fbjhku ioy fbjfr kjmyhg % IFS=, ; printf %s "$*" #OUTPUT# kijhg, fbjhku,,,ioy fbjfr, kjmyhg 

Étant donné que $* a la qualité spéciale spécifiée par POSIX pour fractionner le tableau d'arguments de paramètre de position du shell sur le premier caractère de $IFS vous pouvez facilement convertir des parties de données aussi simplement que cela. Vous pouvez "quote" -protéger le tableau des arguments et toujours le split sur n'importe quel caractère que vous aimez. Tant que tu l'as bien compris la première fois.

APPEND / PREPEND

POSIX spécifie également des qualités spéciales à "$@" . Mis à part les forms d'adressage "$1"... eval "\${$#}" pour chaque argument, le paramètre "$@" – lorsqu'il est cité – étend sans risque à tous les arguments du shell tels qu'ils étaient set valeur actuelle de $IFS. Donc, si vous voulez append une list au début de votre tableau, procédez comme suit:

 set -- $list "$@" 

Pour la tête / queue:

 set -- $head "$@" $tail 

Pour sortingpler votre tableau:

 set -- "$@" "$@" "$@" 

ALTOGETHER MAINTENANT

À less que votre stream de données ne soit très volumineux, les opérations suivantes peuvent être un peu plus rapides que votre opération actuelle (bien que si vous travaillez avec des files, vous feriez mieux d'éviter la décomposition des shell) :

 ( set -f -- ; IFS=, ; while read -r line ; do set -- "$@" $line ; done printf %s "$*" ) | cat >out 

PEUT-ÊTRE TR?

Ce que je ne comprends pas cependant est-ce – qu'est-ce que tu fais? Essayez-vous de replace les returns par des virgules? Je veux dire – datatables sont-elles déjà séparées par des virgules, à l'exception des nouvelles lignes? Si c'est le cas:

 tr '\n' ',' <in >out