Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I have a text file which contains (among others) the following lines:

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

How can I

  • get the 2 lines from this text file (they will always contain }Einleitung resp. }Grundlagen} and
  • extract the 2 page numbers (in this case 27 and 35),
  • calculate the difference 35-27 = 8 and
  • save the difference (8) of the two numbers in a variable

Perhaps with a bash script in Mac OS X?

share|improve this question
    
var=$({ grep -Eo '(Einleitung|Grundlagen)\}.[0-9]+.'|sort -r|tr '\n' ' '| tr -d -c '0-9 '|awk '{print $1 - $2}'; }</tmp/inputfile) –  artistoex Dec 12 '11 at 12:52

4 Answers 4

up vote 3 down vote accepted

I do not know if Mac OS X has awk. If it does, this should work:

This should work:

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

How it works:

  • FS="[{}]+" sets the field separator to any combination of curly brackets.
  • $4 refers to the third filed on the line (separated by curly brackets).
  • DIFFERENZ=$(...) evaluates the command ... and stores the ouput in DIFFERENZ.
share|improve this answer
2  
    
thanks, that works well with my example. How do I have to write a chapter title which contains a space like Ergebnisse und Diskussion? I tried with if ($3=="Ergebnisse und Diskussion"), but that does not seem to find the correct line –  Martin Dec 12 '11 at 12:24
    
@Martin: Spaces are treated as separators. if ($3=="Ergebnisse" && $4=="und" && $5=="Diskussion") should work. But the page number will no longer be stored in $4. I'll update my answer. –  Dennis Dec 12 '11 at 12:29
    
thank you for your help - sorry, I should have directly asked for the more complicated string, but I did not think about this possible complication –  Martin Dec 12 '11 at 12:32
1  
@Dennis: and now your answer looks like mine :) –  akira Dec 12 '11 at 13:41

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
}

you can call it via:

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

it will print 8. you could store that number in a bash-variable like this:

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

if you need it more tight you could also rewrite calc.awk to be not a separate file but a one-line:

$> nr=`awk 'BEGIN{FS="}{";g=0;e=0}/Einleitung/{e=$3;}/Grundlagen/{g=$3;}END{print g-e;}' < in.txt`
share|improve this answer

Pure bash 4.x, and shows the differences for every chapter:

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"
share|improve this answer
$ DIFFERENCE=$(( $( cat FILENAME | grep Grundlagen | head -n1 | cut -c26-27 ) - $( cat FILENAME | grep Einleitung  | head -n1 | cut -c26-27 ) ))
$ echo $DIFFERENCE
8

This requires that the lines always look exactly like this (i.e. no different headline), because of the cut.

share|improve this answer
1  
it wont even work with different numbers, lets say 1 or 100 –  akira Dec 12 '11 at 12:03
    
@akira If there are that many pages between introduction and fundamentals chapter headlines, he's doing something wrong :-) But you're right of course. –  Daniel Beck Dec 12 '11 at 12:10
    
@DanielBeck: Thank you for your anwer! As you already state (and @akira says), the usage of this solution is quite limited because the numbers have to be exactly at the same position each time. The solutions with awk are more flexible. –  Martin Dec 12 '11 at 12:28
    
@Martin While you're right, you never even hinted that e.g. you want to apply a solution to other chapter names. Quite the opposite with your first list item... –  Daniel Beck Dec 12 '11 at 13:28
    
@DanielBeck: this is true - my question was incomplete. –  Martin Dec 12 '11 at 15:12

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.