Выведите строку, которая соответствует условиям в разных строках с помощью awk

полный новичок. С помощью awk можно напечатать следующее:

w171930 t1 Y z2545377 <--- print this line
w171930 t2 X z4495648
w171931 t1 Y z2555698 <--- print this line
w171931 t2 X z5505690
w171932 t1 Y z2554345 <--- print this line
w171932 t2 X z5507345
w171933 t1 Y z2214694
w171933 t2 Y z8022710
w171933 t3 Y z2143462
w171933 t4 Y z6217556
w171933 t5 Y z9608343
w171933 t6 Y z9984446
w171933 t7 Y z2985572
w171933 t8 Y z6334512 <--- print this line
w171933 t9 X z6503375
w171943 t1 Y z2441603 <--- NO print this line
w171943 t2 X z4644534
w171943 t3 Y z2164440
w171944 t1 Y z2165532

Найдите $3 == "X" и напечатайте предыдущую строку, если в следующей строке есть $2 == "t1"

Цель

w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512

Мне удалось напечатать только предыдущую строку, но я не знаю, как выполнить полное условие

awk '$3 == "Y" { Y=$0; next; } { if ($3 =="X") print Y;}'

извиняюсь, если не правильно выражаюсь

enter image description here

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
2
0
60
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

awk '$2=="t1"{ if(prev2!="" && prev!="") print prev2 }
     { prev=($3=="X"?prev2:""); prev2=$0 }' input
  • $2=="t1" только для строк, где второй элемент = "t1". Когда prev и prev2 имеют значение, мы должны вывести это значение.
  • prev будет содержать значение prev2, когда третий элемент равен "X"
  • prev2 будет иметь значение строки, которую нужно вернуть.
Ответ принят как подходящий

Другое решение с awk:

$ awk '$2=="t1" && third=="X"{print line2}
       {line2=line1; line1=$0; third=$3}' ip.txt
w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512
  • line1 будет иметь предыдущую строку, а line2 будет иметь предыдущую, но одну строку
  • third сохраняет содержимое 3-го поля предыдущей строки
  • когда 2-е поле текущей строки равно t1, проверьте, является ли 3-е поле предыдущей строки X, и если да, напечатайте предыдущую, но одну строку

ваше решение предлагает мне следующее: awk '$2 == "t1" {if (key == "X") print a_copy} {a_copy=prev;prev=$0;key=$3}' file где мы печатаем копию предыдущей строки.

Carlos Pascual 10.04.2022 10:34

Что касается вашего требования:

Search on $3 == "X" and print the previous line if the next line has a $2 == "t1"

Как и в жизни, в программном обеспечении гораздо проще делать вещи, основываясь на том, что ПРОИЗОШЛО, а не на том, что произойдет, поэтому не пишите требования, основываясь на том, что будет СЛЕДУЮЩЕЕ, пишите их на основе того, что было в ПРЕДЫДУЩИХ вещах, и вы сами. Нам будет намного легче концептуализировать и написать код для их реализации. В этом случае ваше требование должно быть записано как:

If $2 == "t1" in the current line and $3 == "X" in the previous line then print the line before that.

что приводит к очевидной реализации:

$ awk '($2=="t1") && (p3=="X") {print pp0} {pp0=p0; p0=$0; p3=$3}' file
w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line

Вы можете сделать это с помощью регулярное выражение, если хотите, что можно сделать в Perl:

perl -0777 -nE 'while (/^.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/gm) {print $&}' file

Или, немного изменив регулярное выражение, вы можете использовать GNU Grep:

grep -ozP '.*\R(?=(?:\S+\s){2}X\s\S+\R\S+\st1)' file | tr -d '\000'

Или ruby:

ruby -e 'puts $<.read.scan(/(.*\R)(?=(?:\S+\s){2}X\s\S+\R\S+\st1)/)' file

Любой из них (с вашим примером ввода) печатает:

w171930 t1 Y z2545377 <--- print this line
w171931 t1 Y z2555698 <--- print this line
w171932 t1 Y z2554345 <--- print this line
w171933 t8 Y z6334512 <--- print this line

tr -d '\000' удаляет окончания строк NUL, вставленные GNU grep.

dawg 09.04.2022 18:10

немного многословно, но он выполняет свою работу:

<<<"${aa}" mawk '

 BEGIN {
       _+=++_
 } {
     do {____=$((__=$_)<"") 

     } while($(_+getline)=="Y")
   
     if(___<("X"==$++_)) {

       printf("%s%.*s",____,\
           (___=__!="t1")<_,ORS) }; -—_}'

w171930 t1 Y z2545377
w171931 t1 Y z2555698
w171932 t1 Y z2554345
w171933 t8 Y z6334512

Другие вопросы по теме