lidia
lidia

Reputation: 3193

awk + one line awk syntax to print only once the second field if "true" word matched

I don't know how to do this with awk But my target is to create awk one line syntax in order to print the second field ($2) if all first field ($1) are true

for example

I have the file:

   true my_name_is_lenon
   true my_name_is_lenon
   true my_name_is_lenon
   false my_name_is_lenon
   true my_name_is_lenon

   false my_dog_is_fat
   true my_dog_is_fat
   true my_dog_is_fat

   true I_am_very_tall
   true I_am_very_tall
   true I_am_very_tall

   true my_ball_is_fine
   true my_ball_is_fine

the awk will print only the following:

 I_am_very_tall
 my_ball_is_fine

Because I_am_very_tall , my_ball_is_fine get true on the first field without false

my_dog_is_fat , my_name_is_lenon not printed because the false word on the first field

The rule is to print the second field if no false word on the first field! (Of all the same sentence on the second field)

lidia

Upvotes: 4

Views: 34626

Answers (7)

rahul
rahul

Reputation: 591

Here is a one liner:

awk '{$1=="false" ? false[$2]="false" : true[$2]="true"} END{for (i in true) if   (!false[i]) {print i} }'

my_ball_is_fine I_am_very_tall

Upvotes: 0

DanielAjoy
DanielAjoy

Reputation: 31

Here is another way:

gawk '{a[$2]=a[$2] || $1=="false"} END {for (i in a) if (!a[i] && i) print i}' a.txt

my_ball_is_fine
I_am_very_tall

Upvotes: 0

ghostdog74
ghostdog74

Reputation: 342819

Assuming each block is of the same category.

$ awk -vRS= '!/false/' file | uniq | awk '{print $NF}'
I_am_very_tall
my_ball_is_fine

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 247052

Another compact solution.

awk '
  $1 == "true" && ! ($2 in false) {true[$2]}
  $1 == "false" {false[$2]; delete true[$2]}
  END {for (word in true) print word}
' true.txt

Upvotes: 0

Dennis Williamson
Dennis Williamson

Reputation: 360465

Here is one way:

awk '{if ($1 == "false") {array[$2] = $1} else if (array[$2] != "false") array[$2] = $1} END {for (i in array) if (array[i] == "true") print i}' inputfile

Edit:

Here it is on multiple lines:

awk '{if ($1 == "false") 
         {array[$2] = $1} 
     else if (array[$2] != "false") 
         array[$2] = $1} 
     END {for (i in array)
             if (array[i] == "true") 
                 print i}
' inputfile

Upvotes: 7

Dimitre Radoulov
Dimitre Radoulov

Reputation: 28000

And another one:

awk 'END { 
  for (A in all)  
    if (!(A in ko)) print A
  }
NF { all[$2] } 
$1 == "false" { ko[$2] }
' infile

If you want to preserve the original order, you'll need more code though.

Upvotes: 0

Callie J
Callie J

Reputation: 31316

I'm not sure it is possible as an awk one-liner. At least not easily. Is awk absolutely required? As there are one line shell solutions available if awk is just part of the solution.

For example, this is a shell one-liner (just a long line):

awk '{ print $2 }' < {infile} | while read line; do grep -i "false $line" {infile} > /dev/null || echo $line; done | uniq

It's not efficient, but it does do the job.

In comparison, the shortest awk solution I've got is about 25 lines (which I can drop here in here if you want -- leave a comment and I'll update this accordingly). But this would then mean you could save this to a file and execute awk -f alltrue.awk < {infile}. I'm not sure this strictly classes as a perl one-liner though :-)

A better understanding of what you're ultimately trying to achieve or what this is for might be useful.

Upvotes: 0

Related Questions