awk 编程 - 有条件地更改字段值

awk 编程 - 有条件地更改字段值

我是 awk 编程的新手。这篇文章是为了澄清一个疑问。我有这样的文件:

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

其中第 4 列是字符串。我想根据第 4 列对第 3 列进行更改。例如:要读取第 4 列,如果$4=ms那么$3=$3+1

实际上我不知道如何让程序读取字符串 ms。

请帮助我!

答案1

为此,您需要在动作块内使用条件语句{}

语法是if ( expr ) statement

因此,要匹配第 4 列的条件ms,然后在条件匹配时重新分配第 3 列的值:

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

然后使用以下方法打印整行print $0

完整命令如下:

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

答案2

如果条件简单,您可以使用模式匹配来修改行。

假设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

test.txtawk 命令读取awk 脚本的内容并/ms$/ {$3++} {print}逐行运行。该脚本可以重写为:

/ms$/ {$3++}

      {print}
  • 脚本中的大括号内有两个动作:{}
    • 第二个更容易解释:它只是打印出整行。
    • 第一个在操作前包含模式规范。操作只会在匹配的行上运行。模式写在斜杠内://
      • ms$ms表示每行在行末都有该字符串$(美元符号表示该字符串应该是行中的最后一个)。
      • 此操作$3++将第三列的值增加一。

请注意,该{print}操作将始终运行,因为此操作没有模式,但{$3++}仅当在行尾找到字符串“ms”时,该模式才会运行。此外,增量发生在打印之前,因此所有必要的修改都将按时执行。

答案3

输入文件:

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

分号是可有可无的

答案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 中的表达式 before{}被视为if语句,因此它的工作方式与 OP 要求的一样:如果 $4 是 "ms",则增加 $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

相关内容