如何从两个字符串中提取两个数字并计算 Bash 中的差值?

如何从两个字符串中提取两个数字并计算 Bash 中的差值?

我有一个文本文件,其中包含以下几行(其中包括):

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

我怎么能够

  • 从此文本文件中获取 2 行(它们将始终包含}Einleitungresp.}Grundlagen}
  • 提取 2 个页码(在本例中为 27 和 35),
  • 计算差异35-27 = 8
  • 将两个数字的差 ( 8) 保存在变量中

也许使用 Mac OS X 中的 bash 脚本?

答案1

我不知道 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

答案2

计算.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`

答案3

纯 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"

答案4

$ DIFFERENCE=$(( $( cat FILENAME | grep Grundlagen | head -n1 | cut -c26-27 ) - $( cat FILENAME | grep Einleitung  | head -n1 | cut -c26-27 ) ))
$ echo $DIFFERENCE
8

这就要求各行看起来总是完全像这样(即没有不同的标题),因为cut

相关内容