tags:

views:

130

answers:

6

hi all

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

A: 

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.

Chris J
A: 

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
Dennis Williamson
hi denniscan you change the awk like radoulov awk? (not one line)THXlidia
lidia
@lidia: OK, but your question said "awk one line syntax".
Dennis Williamson
I think its better not one line (in the script its not look fine)
lidia
A: 

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.

radoulov
A: 

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
glenn jackman
+1  A: 

Assuming each block is of the same category.

$ awk -vRS= '!/false/' file | uniq | awk '{print $NF}'
I_am_very_tall
my_ball_is_fine
ghostdog74
sorry but this awk not work try the follwoing 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
lidia
A: 

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
DanielAjoy