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