Как извлечь два числа из двух строк и рассчитать разницу в 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?

4 ответа

Решение

Я не знаю, есть ли в 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 g-e;         # 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 g-e;}' < in.txt`

Чистый 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,

Другие вопросы по тегам