Comment interagir à partir de mots dans un texte? (Script shell)

J’ai un fichier actuellement dans le formulaire

location1 attr attr ... attr location2 attr attr ... attr ... locationn attr atrr ... attr 

Ce que je veux faire, c’est parcourir chaque ligne, saisir l’emplacement (premier champ), puis parcourir les atsortingbuts. Jusqu’à présent, je sais comment saisir le premier champ, mais pas parcourir les atsortingbuts. Il y a également un nombre différent d’atsortingbuts pour chaque ligne.

 TEMP_LIST=$DIR/temp.list while read LINE do x=`echo $LINE | awk '{print $1}'` echo $x done<$TEMP_LIST 

Quelqu’un peut-il me dire comment parcourir les atsortingbuts? Je veux obtenir l’effet comme

 while read LINE do location=`echo $LINES |awk '{print $1}'` for atsortingbute in atsortingbutes do something involving the $location for the line and each individual $atsortingbute done<$TEMP_LIST 

Je travaille actuellement sur ksh shell, mais tout autre shell Unix est correct, je vais trouver comment traduire. Je suis vraiment reconnaissant si quelqu’un pouvait aider car cela me permettrait de gagner beaucoup de temps. Je vous remercie.

Similaire à la solution de DreadPirateShawn, mais un peu plus simple:

 while read -r location all_attrs; do read -ra attrs <<< "$all_attrs" for attr in "${attrs[@]}"; do : # do something with $location and $attr done done < inputfile 

La seconde ligne de read utilise la fonctionnalité de base de bash.

Cela pourrait fonctionner dans d’autres shells aussi, mais voici une approche qui fonctionne dans Bash:

 #!/bin/bash TEMP_LIST=temp.list while read LINE do # Split line into array using space as delimiter. IFS=' ' read -a array <<< $LINE # Use first element of array as location. location=${array[0]} echo "First param: $location" # Remove first element from array. unset array[0] # Loop through remaining array elements. for i in "${array[@]}" do echo " Value: $i" done done < $TEMP_LIST 

Comme vous utilisez déjà awk dans votre code affiché, pourquoi ne pas apprendre à utiliser awk, car il est conçu pour ce type de problème.

 while read LINE do location=`echo $LINES |awk '{print $1}'` for atsortingbute in atsortingbutes do something involving the $location for the line and each individual $atsortingbute done<$TEMP_LIST 

est écrit en awk comme

 #!/bin/bash tempList="MyTempList.txt" awk '{ # implied while loop for input records by default location=$1 print "location=" location # location as a "header" for (i=2;i 

Si vous voulez enregistrer votre sortie, utilisez awk '{.....}' ${tempList}> ${tempList}.new

Awk a de nombreux vars qu'il définit comme il lit vos fichiers. NF signifie NumberOfFields pour la ligne en cours. Donc, la boucle for commence au champ 2 et affiche tous les champs restants sur cette ligne dans le format fourni (changez selon vos besoins). Le i<=NF permet d'imprimer tous les élems sur une ligne. Parfois, vous voulez que le 3ème soit en ligne, vous pouvez donc effectuer des calculs sur la valeur stockée dans NF, comme thirdFromLast=$(NF-3) . Pour toutes les variables qui sont des nombres, vous pouvez le "déréférencer" en tant que valeur et demander à awk d'imprimer la valeur stockée dans le champ $ N (th). c'est à dire essayer

 print "thirdFromLast="(NF-3) print "thirdFromLast="$(NF-3) 

... pour voir la différence que $ fait sur une variable contenant un nombre.

(Pour de grandes quantités de données, 1 processus awk sera considérablement plus efficace que l'utilisation de sous-processus pour rassembler des parties de fichiers.)

Travaillez également à travers le tutoriel awk de ce tutoriel

IHTH