Как извлечь два числа из двух строк и рассчитать разницу в Bash?

У меня есть текстовый файл, который содержит (среди прочего) следующие строки:

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

Как я могу

  • Получить 2 строки из этого текстового файла (они всегда будут содержать }Einleitung соответственно. }Grundlagen} и
  • Извлеките 2 номера страниц (в этом случае 27 и 35),
  • Вычислить разность 35-27 = 8 и
  • Сохраните разность ( 8 ) двух чисел в переменной

Возможно, с помощью скрипта bash в Mac OS X?

Я не знаю, есть ли у Mac OS X awk. Если это так, это должно работать:

Это должно работать:

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

Как это работает:

  • FS="[{}]+" устанавливает разделитель полей в любую комбинацию фигурных скобок.
  • $4 относится к третьей поданной на линии (разделенной фигурными скобками).
  • DIFFERENZ=$(...) оценивает команду ... и сохраняет выход в 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 } 

Вы можете позвонить через:

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

Он напечатает 8 . Вы можете сохранить это число в переменной bash следующим образом:

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

Если вам это нужно более жестко, вы также можете переписать calc.awk не как отдельный файл, а в одну строку:

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

Pure bash 4.x и показывает различия для каждой главы:

 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 

Это требует, чтобы линии всегда выглядели точно так же (т. Е. Ни один другой заголовок) из-за cut .

Давайте будем гением компьютера.