программирование awk - условное изменение значения поля

Я новичок в программировании на awk. Этот пост должен прояснить сомнение. У меня есть файл, как это:

70 17 5 mb
71 18 6 ms
72 19 7 ml
73 20 8 mw

, в котором 4-й столбец является строкой. Я хочу внести изменения в 3-й столбец по отношению к 4-му столбцу. Например: прочитать 4-й столбец, если $4=ms, то $3=$3+1.

На самом деле я не знаю, как заставить программу читать строку ms.

Пожалуйста, помогите мне в этом!

4
задан 26 June 2013 в 12:56

4 ответа

OP ответила на их собственный вопрос, когда они описали условия. Это должно было быть переведено как так:

$ awk '$4=="ms"{$3=$3+1};1' input.txt                  
70 17 5 mb
71 18 7 ms
72 19 7 ml
73 20 8 mw

Выражение прежде {} в awk рассматривается как if оператор, таким образом, это работает OP, спросил: если 4$ являются "мс", инкремент 3$. 1 после {}; просто средства print. Последовательность также важна, потому что мы проверяем условия сначала и затем печатаем.

Как альтернатива подходу awk, Python может сделать так также. Небольшой сценарий ниже может сделать задание. Это может быть превращено в остроту также, но для удобочитаемости, я предоставляю только сценарий здесь

#!/usr/bin/env python
from __future__ import print_function
import sys

with open(sys.argv[1]) as f:
     for line in f:
          words = line.strip().split()
          if words[3] == "ms":
             words[2] = str(int(words[2]) + 1)
          print(" ".join(words))

И выполненный образец:

$ ./increment_field.py input.txt                                                                                  
70 17 5 mb
71 18 7 ms
72 19 7 ml
73 20 8 mw
0
ответ дан 26 June 2013 в 12:56

Входной файл:

cat f.txt
70 17 5 mb
71 18 6 ms
72 19 7 ml
73 20 8 mw

Возможные решения:

1. awk '$4=="ms",$3=$3+1;{print}' f.txt
70 17 5 mb
71 18 7 ms
71 18 7 ms
72 19 7 ml
73 20 8 mw

(не знаю, почему, но нехорошо - дублируются строки (и) цели)

2. awk '{if ($4=="ms"){$3=$3+1}; print}' f.txt
70 17 5 mb
71 18 7 ms
72 19 7 ml
73 20 8 mw

( работал как ожидалось )

3. awk '{if ($4=="ms"){$3=$3+1} print}' f.txt
70 17 5 mb
71 18 7 ms
72 19 7 ml
73 20 8 mw

( точка с запятой " ; " не является необходимым )

4. awk '{if ($4=="ms"){$3=$3+1} else {$3=$3/2}; print}' f.txt
70 17 2.5 mb
71 18 7 ms
72 19 3.5 ml
73 20 4 mw

( работал как ожидалось и более ... )

5. awk '{if ($4=="ms"){$3=$3+1} else {$3=$3/2} print}' f.txt
70 17 2.5 mb
71 18 7 ms
72 19 3.5 ml
73 20 4 mw

( точка с запятой "; " является необязательной )

0
ответ дан 26 June 2013 в 12:56

Если условие простое, вы можете использовать сопоставление с образцом для изменения линий.

Предполагая, что test.txt содержит пример данных:

cat test.txt
70 17 5 mb
71 18 6 ms
72 19 7 ml
73 20 8 mw

Давайте рассмотрим следующую строку и ее вывод:

awk '/ms$/ {$3++} {print}' test.txt
70 17 5 mb
71 18 7 ms
72 19 7 ml
73 20 8 mw

Команда awk считывает содержимое test.txt и запускает скрипт awk /ms$/ {$3++} {print} в каждой строке. Сценарий может быть переписан как:

/ms$/ {$3++}

      {print}
  • В фигурных скобках есть два действия: {}.
    • Второй легче объяснить: он просто печатает всю строку.
    • Первый содержит спецификацию шаблона перед действием. Действие будет выполняться только на совпадающих строках. Шаблон написан внутри косой черты: //.
      • ms$ означает, что каждая строка имеет строку ms в конце строки $ (знак доллара указывает, что строка должна быть последней в строке).
      • Действие $3++ увеличивает значение третьего столбца на единицу.

    Обратите внимание на {print} ] действие всегда будет выполняться, потому что для этого действия нет шаблона, но шаблон {$3++} будет выполняться только в том случае, если в конце строки найдена строка «ms». Также увеличение происходит перед печатью, поэтому все необходимые модификации будут выполнены вовремя.

0
ответ дан 26 June 2013 в 12:56

Чтобы сделать это, необходимо использовать условный оператор в блоке действия {}.

Синтаксис if ( expr ) statement

Таким образом для соответствия условию, где 4-й столбец ms и затем повторно присвойте значение для 3-го столбца, когда условие будет подобрано:

if ($4 == "ms") $3=$3+1

и затем распечатайте целое использование строки print $0

Таким образом, полная команда похожа на это:

awk '{ if ($4 == "ms") $3=$3+1; print $0 }'

8
ответ дан 26 June 2013 в 12:56

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

Похожие вопросы: