awk + одна строка синтаксис awk для печати только один раз второго поля, если слово «true» соответствует - PullRequest
4 голосов
/ 23 июля 2010

Я не знаю, как это сделать с помощью awk, но моя цель - создать синтаксис с одной строкой в ​​awk, чтобы напечатать второе поле ($ 2), если все первое поле ($ 1) истинно

дляпример

У меня есть файл:

   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

awk напечатает только следующее:

 I_am_very_tall
 my_ball_is_fine

Поскольку I_am_very_tall, my_ball_is_fine получает true в первом поле без false

my_dog_is_fat, my_name_is_lenon не напечатано, поскольку ложное слово в первом поле

Правило состоит в том, чтобы печатать второе поле, если в первом поле нет ложного слова!(Из всех одинаковых предложений на втором поле)

Лидия

Ответы [ 7 ]

7 голосов
/ 23 июля 2010

Вот один из способов:

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

Редактировать:

Здесь несколько строк:

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
1 голос
/ 23 июля 2010

Предполагая, что каждый блок относится к той же категории.

$ awk -vRS= '!/false/' file | uniq | awk '{print $NF}'
I_am_very_tall
my_ball_is_fine
0 голосов
/ 02 сентября 2013

Вот один вкладыш:

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

0 голосов
/ 24 июля 2010

Вот еще один способ:

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
0 голосов
/ 23 июля 2010

Еще одно компактное решение.

awk '
  $1 == "true" && ! ($2 in false) {true[$2]}
  $1 == "false" {false[$2]; delete true[$2]}
  END {for (word in true) print word}
' true.txt
0 голосов
/ 23 июля 2010

И еще один:

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

Если вы хотите сохранить исходный порядок, вам потребуется больше кода.

0 голосов
/ 23 июля 2010

Я не уверен, что это возможно в качестве одной строки в awk.По крайней мере, не легко.Требуется ли awk?Так как доступны однострочные решения оболочки, если awk является лишь частью решения.

Например, это однострочная оболочка (просто длинная строка):

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

Этоне эффективно, но оно делает работу.

Для сравнения, самое короткое awk-решение, которое у меня есть, составляет около 25 строк (которые я могу опустить здесь, если хотите - оставьте комментарий, и я обновлю его соответственно).Но тогда это может означать, что вы можете сохранить это в файл и выполнить awk -f alltrue.awk < {infile}.Я не уверен, что это строго классы как однострочный perl: -)

Лучшее понимание того, чего вы в конечном итоге пытаетесь достичь или для чего это может быть полезным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...