Comparing lines of data

Total UNIX Rookie, but I'm learning. I have columns of integer data separated by spaces, and I'm using a Mac terminal.

What I want to do:

  1. Compare "line 1 column 2" (x) to "line 2 column 2" (y); is y-x>=100?
  2. If yes, display difference and y's line number
  3. If no, increment x and y by one and repeat

How I am going about it:

sed -n '1,2 p' datafile | cut -d' ' -f1 #gives me the two fields of interest

Where do I go from here?

Is this a homework?

This is for research. The data is power and its odd harmonics, and I am looking for a way to ID transients without having to graph everything. I just chose simple numbers so I can understand the mechanics. Thanks.

OK,
please post a sample input file and an example of the expected output. Please use code tags: Video tutorial on how to use code tags in The UNIX and Linux Forums.

With assumptions about your data and its structure:

awk '!(NR%2) && (d=$2-x)>=100{print d,NR}{x=$2}' file

data sample, I modified the second column for simplicity:

1.94183e+05  7.8e+04  1.09609e+04  -2.51962e+03  2.58938e+03  -1.78130e+04  8.17326e+03  9.09750e+03  
1.95223e+05  7.8e+04  1.08129e+04  -2.50996e+03  2.23601e+03  -1.76457e+04 8.53983e+03  8.87947e+03  
1.95826e+05  7.8e+04  1.08992e+04  -2.80696e+03  2.35323e+03  -1.77662e+04  8.43230e+03  8.83312e+03  
1.94827e+05  7.62589e+04  1.11074e+04  -2.79142e+03  2.60123e+03  -1.80548e+04  8.05580e+03  8.95096e+03  
1.92552e+05  7.8e+04  1.10656e+04  -2.03271e+03  3.18014e+03  -1.78507e+04  7.77928e+03  9.32247e+03  
1.91165e+05  7.9e+04  1.07475e+04  -1.78148e+03  3.61320e+03  -1.76183e+04  7.69183e+03  9.39564e+03  
1.91355e+05  7.9e+04  1.07990e+04  -2.17165e+03  3.17912e+03  -1.79394e+04  7.87802e+03  9.13235e+03  
1.90294e+05  7.8e+04  1.08781e+04  -2.42501e+03  2.58355e+03  -1.82862e+04  8.15985e+03  8.91582e+03  
1.88968e+05  7.8e+04  1.03374e+04  -2.25564e+03  2.31198e+03  -1.81390e+04  8.48529e+03  8.75009e+03  
1.89367e+05  7.8e+04  1.01039e+04  -1.94181e+03  2.55877e+03  -1.76577e+04  8.55628e+03  8.80059e+03  

---------- Post updated at 11:21 AM ---------- Previous update was at 11:19 AM ----------

and I expect that the output will be:
line 5: 1741.1
line 6: 1000

---------- Post updated at 11:27 AM ---------- Previous update was at 11:21 AM ----------

elixir_sinari, would you mind explaining?

Your step 3 makes no sense to me. If y-x is not >= 100, then (y+1)-(x+1) can't be >= 100 either. This will just create an very large loop until one of the values overflows. So, until you can explain why this should be done, I'm going to ignore this requirement.

The proposal elixir_sinari makes the assumption that you are only comparing x values on odd numbered lines against y values on even numbered lines. Seeing your sample data and comments in message #6 in this thread, it looks like you want to compare the value in the 2nd column of your input file for every line except the 1st.

This slight modification to elixir_sinari's proposal:

awk '(NR>1) && (d=$2-x)>=100{print d,NR}{x=$2}' file

produces the output:

1741.1 5
1000 6
1741.1 14
1000 15
1741.1 23
1000 24

with your sample data. Is this what you wanted?

Yes indeed! Would you mind translating into English? I don't get how it knows what x is, and I don't see where the shift to the next line happens...Thanks a ton!

I'll try. First, here is the awk script in a slightly different form:

line 1 awk '
line 2 (NR>1) && (d=$2-x)>=100{print d,NR}
line 3 {x=$2}
line 4 ' file

The line numbers in blue are to make it easy to identify what I'm talking about. They cannot appear in the script.

Line 1 says that we are using awk to perform a sequence of commands on every line of input fed into awk. The single-quotes on lines 1 and 4 contain the awk commands to be evaluated.

The file on line 4 says that input lines to be processed are to be read from a file named file .

Line 2 says that for every line read from file , if the current line number in all of the input files we've read so far is greater than 1 (NR>1) and (&&) after setting d (d=) to be the difference between the 2nd field on this line ($2) and the 2nd field on the previous line (x) it finds that d is greater than or equal to 100 (>=100) it executes the command between the braces which prints the value of d and the current line number (print d,NR).

Since there are no conditions on line 3, the command between braces will be performed on every input line. The command (x=$2) sets x to the value of the 2nd field on the current line. (Note that the commands on the 1st line weren't executed because of the condition (NR>1), but x is set as the last thing to be done on every line read by the command on line 3.)

Lines 2 and 3 are reprocessed in order for every input line read from file .

Note also that you specified (y-x)>=100; not |y-x|>=100. If you meant for the absolute value of the difference to be tested instead, you'll need to adjust the conditions on line 2 and decide if you want the actual difference to be printed or the absolute value of the difference to be printed.

Super impressed, Don. Thank you.