Comment extraire deux nombres de deux cordes et calculer la différence dans Bash?

J'ai un fichier texte qui contient (entre autres) les lignes suivantes:

{chapter}{{1}Einleitung}{27}{chapter.1} {chapter}{{2}Grundlagen}{35}{chapter.2} 

Comment puis-je

  • Obtenez les 2 lignes de ce fichier texte (elles contiendront toujours }Einleitung resp. }Grundlagen} et
  • Extraire les 2 numéros de page (dans ce cas 27 et 35),
  • Calculer la différence 35-27 = 8 et
  • Enregistrer la différence ( 8 ) des deux nombres dans une variable

Peut-être avec un script bash dans Mac OS X?

Je ne sais pas si Mac OS X a awk. Si c'est le cas, cela devrait fonctionner:

Cela devrait fonctionner:

 DIFFERENZ=$(awk 'BEGIN { FS="[{}]+" } { if ($4=="Einleitung") EINLEITUNG=$5 if ($4=="Grundlagen") GRUNDLAGEN=$5 } END { print GRUNDLAGEN-EINLEITUNG }' textfile) 

Comment ça marche:

  • FS="[{}]+" définit le séparateur de champ sur n'importe quelle combinaison de crochets.
  • $4 réfère à la troisième déposée sur la ligne (séparée par des crochets).
  • DIFFERENZ=$(...) évalue la commande ... et stocke la sortie dans DIFFERENZ .

Calc.awk:

 BEGIN { FS="}{"; # split lines by '}{' e=0; # set variable 'e' to 0 g=0; # set variable 'g' to 0 } /Einleitung/ { e=$3; } # 'Einleitung' matches, extract the page /Grundlagen/ { g=$3;} # 'Grundlagen' matches, extract the page END { print ge; # print difference } 

Vous pouvez l'appeler via:

 $> awk -f calc.awk < in.txt 

Il va imprimer 8 . Vous pouvez stocker ce numéro dans une variable bash comme ceci:

 $> nr=`awk -f calc.awk < in.txt` 

Si vous l'avez besoin plus serré, vous pouvez également réécrire calc.awk pour ne pas être un fichier distinct mais une ligne unique:

 $> nr=`awk 'BEGIN{FS="}{";g=0;e=0}/Einleitung/{e=$3;}/Grundlagen/{g=$3;}END{print ge;}' < in.txt` 

Pure bash 4.x, et montre les différences pour chaque chapitre:

 unset page_last title_last page_cur title_cur re='\{chapter\}\{\{[[:digit:]]+\}([^}]+)\}\{([[:digit:]]+)\}' while read -r line; do if [[ $line =~ $re ]]; then title_cur=${BASH_REMATCH[1]} page_cur=${BASH_REMATCH[2]} diff=$((page_cur-page_last)) echo "${diff} pages between \"${title_last}\" and \"${title_cur}\"" title_last=$title_cur page_last=$page_cur fi done < "$myfile" 
 $ DIFFERENCE=$(( $( cat FILENAME | grep Grundlagen | head -n1 | cut -c26-27 ) - $( cat FILENAME | grep Einleitung | head -n1 | cut -c26-27 ) )) $ echo $DIFFERENCE 8 

Cela nécessite que les lignes ressemblent toujours exactement à ceci (c'est-à-dire pas de titre différent), en raison de la cut .