-1
votes

Extraire les valeurs du fichier efficacement

Disons que j'ai ce fichier: version.h xxx

à l'aide d'un script Bash, comment extraire les valeurs dans 3 variables distinctes telles que $ maj == 1 , $ min == 4 et $ bld == 0 ?

J'ai essayé plusieurs approches Autour de cette regex: s / \ _ Version \ s * (\ d *) / Ce qui me permet d'extraire sur chaque ligne la valeur dans le premier groupe de matchs, mais j'ai échoué à trouver une solution élégante.

Par exemple, cela ne fonctionne pas (et a également besoin d'un compteur pour désambiguez les 3 valeurs): xxx


1 commentaires

Pour correspondre à des chiffres, utilisez [0-9] , pas \ d .


3 Réponses :


1
votes

Cela devrait le faire

 maj=$(grep MAJ_VERSION version.h | awk '{print $3}')
 min=$(grep MIN_VERSION version.h | awk '{print $3}')
 bld=$(grep BLD_VERSION version.h | awk '{print $3}')


5 commentaires

@Fluffy Eh bien c'est l'une des formes les plus simples d'Awk. Il imprime simplement la 3ème colonne de son entrée


6 processus et 3 tuyaux ne le font pas exactement "efficacement"! Vous n'avez jamais besoin de GREP lorsque vous utilisez AWK, une commande AWK pourrait produire toutes les valeurs à la fois que vous pourriez alors lire simplement dans la coque d'appel ou enregistrer sous forme de valeurs de tableau.


@Ed Morton, je viens de fournir une solution très simple et de travail. Je n'ai jamais prétendu que c'était le plus efficace. Je suis entièrement d'accord que cela pourrait être mieux


J'ai mentionné l'efficacité non à cause de tout ce que vous avez prétendu, mais parce que la question de l'OPS est de savoir comment extraire des valeurs de fichier efficacement .


OK, cependant, j'aimerais beaucoup voir combien de variations du fichier source pourrait briser ma solution et combien de temps pourrait casser la solution "plus efficace". Par exemple, pour moi quelque chose qui s'appuie sur un ordre spécifique des lignes de saisie pour travailler, je ne l'appellerais pas vraiment "efficace", juste parce qu'il utilise un awk plus sophistiqué ..



2
votes

En supposant que vous utilisez Bash et GNU SED:

$ declare -p maj min bld
declare -- maj="1"
declare -- min="4"
declare -- bld="0"


6 commentaires

Nice one-liner! Comment Maj , min , bld variables capturés? En outre, j'ai un petit problème avec cela, dans un contexte, la version.h est générée sous Windows et contient des fins de ligne CRLF, je me retrouve avec typeet min = $ '4 \ c-m' . Cela provoque une question lors de la réalisation d'opérations arithmétiques telles que $ (($ tha + 1)) . Comment géreriez-vous cela?


Pour ce dernier, je changerais (. *) à ([^ \ r] *)


Pour le premier, considérez ce que je capture sur le côté gauche et ce que je remplace sur le côté rugueux. Ensuite, enquêtez à Bash "Substitution de processus" et à la commande source .


Gnu sed \ l est un boîtier inférieur


Merci pour votre explication! J'ai essayé de changer (. *) à ([^ \ r] *) Premièrement, mais cela ne semble pas fonctionner ... Aucune différence lors de l'exclusion des deux \ r et \ n


Vous pouvez essayer sed -e -e 's / \ r $ //' -e 'ma réponse originale' pour "pré-supprimer" les retours de chariot.



0
votes

Si les valeurs existent toujours dans cet ordre dans le fichier d'entrée: xxx pré>

S'il y a plus que les 3 lignes que vous nous montrez dans le fichier d'entrée puis modifier l'AWK à: P >

awk '/^#define.*VERSION/{sub(/_.*/,"",$2); f[$2]=$3} END{print f["MAJ"], f["MIN"], f["BLD"]}' file


2 commentaires

Merci pour votre entrée approfondie, j'ai un dernier problème avec cela (répétant le commentaire ci-dessus): Dans certains contextes, la version.h est générée sous Windows et contient des fins de ligne CRLF, je vous retrouve avec Typeset min = $ '4 \ C-M '. Cela provoque une question lors de la réalisation d'opérations arithmétiques telles que $ (($ tha + 1)) . Comment géreriez-vous cela?


lancer dans un sub (/ \ r /, "") avant les références à 3 $ , par exemple. {sub (/ \ r /, ""); Printf "% s", 3 $} .