Search code examples
bashfilelines

comparing adjacent lines in a single file with bash


Short version: How to make a loop in bash that reads a file log.dat by pairs of lines, compares the second one to "0.0", and in case they match outputs another one, otherwise the second one.

Long version: I have a text file with positions of an object. Positions are determined by two different methods, one is more precise and accurate, but sometimes it fails, and another one is more robust but less accurate. The problem is, I want to minimize the error throughout the data and keep my script in bash.

data example:
timestep1 alg2 15.326785087600001
timestep1 alg1 15.19699239146999
timestep2 alg2 0.0
timestep2 alg1 15.244353796926141


Solution

  • You can do this by looping over the file with a while-loop and read:

    while IFS='' read -r ONE || [[ -n $ONE ]]; do
      read -r TWO
      if [[ $TWO == "0.0" ]]; then # string comparison, not numeric.
        { read -r THREE || [[ -n $THREE ]]; } && echo $THREE;
      fi
    done < "log.dat"
    

    Break down:

    • IFS='' (or IFS=) preservers leading/trailing whitespace in each line read via read. (Bash usually treats whitespace as a word delimiter: this prevents that behavior)

    • -r prevents backslash escapes from being interpreted

    • || [[ -n $ONE ]] prevents the last line in the input file from being ignored if it doesn't contain a line-ending character such as \n or \c\r: (read returns a non-zero exit code when it encounters EOF).