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
2
  • 1
    Should the first line always be printed or never? Commented Sep 8, 2015 at 15:53
  • Yes The lines are log entries and I am looking for the lines a user started and stopped working Commented Sep 8, 2015 at 16:27

2 Answers 2

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
4
  • Thank you very much. This worked perfectly. Would you mind annotating commands? I am not certain I follow the logic. Commented Sep 8, 2015 at 18:21
  • @rcjohnson Sure, I added an explanation Commented Sep 8, 2015 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. Commented Sep 8, 2015 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. Commented Sep 8, 2015 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
2
  • Good for previous and what about next? Commented Sep 8, 2015 at 16:12
  • verified that this works only for the first occurrence but not the last as well Commented Sep 8, 2015 at 16:18

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.