0

I have two columns like this:

(A)        (B)
Adam       30 
Jon        55 
Robert     35
Jokim      99
Adam       32
Adam       31
Jokim      88  

I want an AWK script to check if Adam( or any name ) in column A becomes 30 in column B then delete all Adam names from column A, it does not matter whether Adam becomes 31 or 32 later, and then print the results.

I have a log list in reality and I do not want the code to be depended on "Adam". So, What I want exactly is basically wherever 30 is existed in $2 so delete the respective value in $1 and also search in $1 to find all values which are the same as the deleted value.

Adam
  • 5
  • 6
  • Are you German? Adam "becomes" doesn't make sense. Do you mean specifically remove all Adam lines specifically when the B value for A=Adam is exactly 30? Anyway, what have you tried, and how did it fail? – tripleee Mar 30 '16 at 07:36
  • I think the problem here is the lack of a rewind function. AFAIK awk doesn't have one. If so then you most likely want this question http://stackoverflow.com/questions/28544105/awk-go-through-the-file-twice-doing-different-tasks – Philip Couling Mar 30 '16 at 07:42
  • You should be clear about what happens if there are other Adam entries before the one which has a 30 in (B). It will be very easy in Awk to remove the entries from the 30 and onward (as it only requires one traversal), but a little harder to remove all the Adams only if there is an Adam,30 anywhere in the file. – chthonicdaemon Mar 30 '16 at 07:45
  • I have a log list in reality and I do not want the code to be depended on "Adam". So, What I want exactly is basically wherever 30 is existed in column B so delete the respective value in column A and also search in column A to find all values which are the same as the deleted value – Adam Mar 30 '16 at 08:49
  • Wat happens when more than one name has a 30? – chthonicdaemon Mar 30 '16 at 08:52
  • Should be deleted. – Adam Mar 30 '16 at 08:58

2 Answers2

0

To remove the entries from the first occurence of Adam, 30:

$1 == "Adam" && $2 == 30 { found = 1 }

!(found && $1 == "Adam")

To remove all Adam entries if any Adam, 30 exists:

$1 == "Adam" && $2 == 30 { found = 1 }

!(found && $1 == "Adam") { lines[nlines++] = $0 }

END { for (i in lines) print lines[i] }

To remove all names which have a 30 the second column:

NR == FNR && $2 == 30 { foundnames[$1] = 1 }

NR != FNR && !($1 in foundnames)

You must call this last version with the input filename twice, ie awk process.awk file.txt file.txt

chthonicdaemon
  • 19,180
  • 2
  • 52
  • 66
  • Thanks for you answer. I have a log list in reality and I do not want the code to be depended on "Adam". So, What I want exactly is basically wherever 30 is existed in column B so delete the respective value in column A and also search in column A to find all values which are the same as the deleted value. – Adam Mar 30 '16 at 08:46
  • 1
    @Adam in your question, you let us start from column A (the "Adam"), now you want to start from col B (30).... can you describe your problem completely and clearly in question? – Kent Mar 30 '16 at 08:50
  • @Adam I've added a solution for the new version of the question with an arbitrary number of names. – chthonicdaemon Mar 30 '16 at 09:15
0

You can read the columns into variables and check the value of the second column for the value you are looking for then sed the file to delete all the column 1 entries:

cp test.txt out.txt && CHK=30 && while read a b; do [ "${b}" = "${CHK}" ] && sed -i "/^${a}/d" out.txt done < test.txt

Note: If you may have regex values in the columns you may need to escape them, also if you possibly have blanks you may want to check for null first before the test on column 2.

And since you specified AWK here is a somewhat elegant awk way to do this, using a check flag to look ahead prior to printing:
awk -vCHK=30 '{if($2~CHK)block=$1; if($1!=block)print}' test.txt