1

I have a tab delimited file:

qrs     John    tuv
abcd    Sam     efgh
ijk     Sam     lmnp
abcd    Sam     efgh
ijk     Sam     lmnp
qrs     John    tuv

I am trying to print the line in which the second field does not match the previous line's value in the second field and to print the line in which the second field does not match the next line.

I've been playing with variations of the following but nothing is quite working like I expect:

awk -F"\t" '{
    name=$3;
    line=$0;
    getline;
    newname=$3;
    newline=$0;
    getline;
    nextname=$3;
    nextline=$0; 
    if (newname != name || name != nextname)print line"\n"nextline }' input.txt
  • 1
    Should the first line always be printed or never? – terdon Sep 8 '15 at 15:53
  • Yes The lines are log entries and I am looking for the lines a user started and stopped working – rcjohnson Sep 8 '15 at 16:27
2

From you comment, I assume it's a log file with login and logout dates, for example:

date1   John    logout
date2   Sam     login
date3   Sam     work1
date4   Sam     work2
date5   Sam     logout
date6   John    login

Use awk:

awk 'NR!=1&&$2!=f{print p"\n"$0} {f=$2; p=$0}' file

Where:

  • NR!=1 is true when awk processes everyline but the first (NR contains the number of the line in the current file)
  • $2!=f compares the second field $2 with the value of the variable f (f will be set later)
    • If both confiftions apply, awk prints the value of p (the previous line, will be set later too), a newline \n and the current line $0.
  • What now happens, is processed every line: The variable f is set to the second field $2 and the variable p to the current line $0. Both will be used in the next iteration (when the next line is processed).

This now prints the first and last occurence of the second field, so the logout and login dates and names. The output would then be:

date1   John    logout
date2   Sam     login
date5   Sam     logout
date6   John    login
  • Thank you very much. This worked perfectly. Would you mind annotating commands? I am not certain I follow the logic. – rcjohnson Sep 8 '15 at 18:21
  • @rcjohnson Sure, I added an explanation – chaos Sep 8 '15 at 18:30
  • Great I didn't see how the variables could be set after the conditions. I'm going to need to re-examine some of my older stuff now. Thank you once again. – rcjohnson Sep 8 '15 at 18:36
  • @rcjohnson They are not set after the conditions, they were set in the last loop and they are now set for the next loop. In the first loop they are not set, they are empty, therefore the condition $2!=f is true then. – chaos Sep 8 '15 at 18:38
1

By specifying a variable with value of $2 try below command:

awk -F"\t" 'NR != 1 { if ( x != $2 ) print $0; } { x = $2 }' file
  • Good for previous and what about next? – Costas Sep 8 '15 at 16:12
  • verified that this works only for the first occurrence but not the last as well – rcjohnson Sep 8 '15 at 16:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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