В AWK пропустить остальную часть текущего действия? - PullRequest
0 голосов
/ 25 января 2019

Спасибо за внимание.

У меня есть сценарий AWK с чем-то вроде этого;

/^test/{
  if ($2 == "2") {
    # What goes here?
  }

  # Do some more stuff with lines that match test, but $2 != "2".
}


NR>1 {
  print $0
}

Я бы хотел пропустить оставшуюся часть действия, но обработать остальные шаблоны / действия в одной строке.

Я пробовал return, но это не функция. Я пробовал next, но это пропускает остальные шаблоны / действия для текущей строки.

Пока я завернул остальную часть действия ^test в else оператора if, но мне было интересно, есть ли лучший подход.

Не уверен, что это имеет значение, но я использую gawk в OSX, установленной через brew (для лучшей совместимости с моей целевой ОС).

Обновление (с решением):

Правки: расширенный пример кода, основанный на ответе @ karakfa.

BEGIN{
  keepLastLine = 1;
}
/^test/ && !keepLastLine{
  printLine = 1;
  print $0;
  next;
}

/^test/ && keepLastLine{
  printLine = 0;
  next;
}

/^foo/{
  # This is where I have the rest of my logic (approx 100 lines), 
  # including updates to printLine and keepLastLine
}

NR>1 {
  if (printLine) {
    print $0
  }
}

Это будет работать для меня, мне даже нравится больше, чем то, о чем я думал.

Однако мне интересно, что, если мое условие keepLastLine было доступно только в цикле for?

Из того, что сказал @karakfa, я понял, что нет структуры управления для выхода только из действия и продолжения работы с другими шаблонами, так что это должно быть реализовано с каким-то флагом (в отличие от ответа @ RavinderSingh13) ).

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Волшебное ключевое слово, которое вы ищете, это else

/^test/{ if($2==2) {  } # do something
         else {  }      # do something else  
       }

NR>1                    # {print $0} is implied. 

по какой-то причине, если вы не хотите использовать else, просто поднимите условие на один вверх (сгладьте иерархию)

/^test/ && $2==2 {  } # do something
/^test/ && $2!=2 {  } # do something else  
# other action{statement}s           
0 голосов
/ 25 января 2019

Если я правильно понял, не могли бы вы попробовать. Я создаю переменную с именем flag, которая будет выделена здесь, если условие внутри блока test для проверки, является ли 2-е поле 2 ИСТИНОЙ, тогда оно будет УСТАНОВЛЕНО. Когда он установлен, остальные инструкции в test BLOCK НЕ будут выполнены. Также сброс значения флага перед началом чтения также для строки.

awk '
{
 found=""
}
/^test/{
  if ($2 == "2") {
    # What goes here?
    found=1
  }
  if(!found){
  # Do some more stuff with lines that match test, but $2 != "2".
  }
}
NR>1 {
  print $0
}'  Input_file


Тестирование кода здесь:

Допустим, следующий файл является Input_file:

cat Input_file
file
test 2 file
test
abcd

После запуска кода, следующего за кодом, мы получим следующий вывод, где, если какая-либо строка имеет ключевое слово test и НЕ имеет $2==2, она также выполнит операторы вне условия test.

awk '
{
 found=""
}
/^test/{
  if ($2 == "2") {
    print "# What goes here?"
    found=1
  }
  if(!found){
   print "Do some more stuff with lines that match test, but $2 != 2"
  }
}
NR>1 {
  print $0
}'   Input_file
# What goes here?
test 2 file
Do some more stuff with lines that match test, but $2 != 2
test
abcd
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...