bash chaîne de tableau avec des espaces et extra délimiteurs

Je suis en train de créer des tableaux de chaînes qui ont de la pipe ("|") comme des séparateurs et des espaces. J'ai été en regardant autour pendant un moment et j'ai reçu près grâce à des sources comme Comment puis-je diviser une chaîne sur un délimiteur dans le Bash?, Fractionnement d'une chaîne en un tableau et un tas plus. Je suis proche, mais il n'est pas assez de travail. Les deux principaux problèmes qu'il y a des espaces dans les chaînes, il y a des délimiteurs de début et de fin, et certains champs sont vides. Aussi, au lieu de simplement en faisant écho aux valeurs, j'ai besoin de les affecter à des variables.
Voici le format de la source de données:

|username|full name|phone1|phone2|date added|servers|comments|

Exemple:

|jdoe | John Doe| 555-1212 | |1/1/11 |  workstation1, server1 | added by me |

Voici ce que j'ai besoin de:

Username: jdoe
Fullname: John Doe
Phone1: 555-1212
Phone2: 
Date_added: 1/1/11
Servers: workstation1, server1
Comments: guest account

Edit: j'ai utiliser sed à dépouiller le premier et le dernier délimiteur et des espaces avant et après chaque séparateur d'entrée est maintenant:

jdoe|John Doe|555-1212||1/1/11|workstation1, server1|added by me

Voici les choses que j'ai essayé:

oIFS="$IFS"; IFS='|'
for line in `cat $userList`; do
  arr=("$line")
  echo "Username: ${arr[0]}"  #not assigning a variable, just testing the output
  echo "Full Name: ${arr[1]}"
  echo "Phone 1: ${arr[2]}"
  echo "Phone 2: ${arr[3]}"
  # etc..
done
IFS="$oIFS"

De sortie:

Username: 
Full Name: 
Phone 1:
Phone 2:
Username: jdoe
Full Name: 
Phone 1:
Phone 2:
Username: John Doe
Full Name: 
Phone 1:
Phone 2:

Autre chose que j'ai essayé:

for line in `cat $userList`; do
  arr=(${line//|/ })
  echo "Username: ${arr[0]}"
  echo "Full Name: ${arr[1]}"
  echo "Phone 1: ${arr[2]}"
  echo "Phone 2: ${arr[3]}"
  # etc
done

De sortie:

Username: jdoe
Full Name: John
Phone 1:
Phone 2:
Username: Doe
Full Name: 555-1212
Phone 1:
Phone 2:

Des suggestions? Merci!!


Résolu: par la première suggestion ci-dessous, le script ressemble maintenant à ceci:

#!/bin/bash
userList=`cat userlist | sed 's/^|//; s/|$//; s/[ ]*|[ ]*/|/g;'`
oIFS="$IFS"; IFS=$'\n'
for line in $userList; do
  IFS='|'
  arr=($line)
  echo "Username: ${arr[0]}"
  echo "Full Name: ${arr[1]}"
  echo "Phone 1: ${arr[2]}"
  echo "Phone 2: ${arr[3]}"
  #etc
done
IFS="$oIFS"

De sortie:

Username: jdoe
Full Name: John Doe
Phone 1: 555-1212
Phone 2: 
Username: jdoe2
Full Name: Jane Doe
Phone 1: 555-1212
Phone 2:

Fonctionne comme un charme, merci beaucoup! Je n'ai pas essayé les autres suggestions ci-dessous, mais je le ferai la prochaine fois que j'ai besoin de faire quelque chose de similaire. Merci à tous!

ce serait trivial en perl ou ruby, aucune raison de ne pas utiliser l'un de ces?
Je suis avec l'utilisation de perl' commentaire mais si vous voulez un bash-seul type d'approche, pourquoi ne pas au moins utiliser avec " sed " ou quelque chose de dépouiller les espaces avant et après les caractères "|" et au moins le rendre plus facile sur vous-même
Perl est une option, mais je ne suis pas familier avec elle. J'ai ajouté un sed ligne à supprimer avant/après séparateurs et des espaces, la mise à jour de question.
c'est aussi trivial en bash, il est en perl ou ruby.
pourrais-je vous suggère d'essayer les mgf réponse ci-dessous à la place. C'est la réponse la plus appropriée à mon humble avis. Aussi, jetez un oeil à mes commentaires à sa réponse.

OriginalL'auteur Martin | 2011-12-30

Leave a Reply

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *