linux - 使用 sed/awk 命令找到模式后修改文本文件的内容

标签 linux bash awk sed

我试图想出一个 Tcl 脚本,但我在 sed/awk 命令中寻找一些东西来使它更快。

该文件包含以下内容:

*Other text*
.....
.....
.....
SECTION LABELS {
lab M1 0 0 0 0 3 1 bot
lab M2 0 0 0 0 3 1 top
} SECTION LABELS

*Other text*
......
......
......
SECTION LABELS {
lab M1:NET 5207 12261 5207 12261 0 2 A
lab M2:NET 6880 5370 6880 5370 0 2 B
lab M1:NET 3454 5386 3454 5386 0 2 alpha
lab M2:NET 3454 5386 3454 5386 0 2 beta
} SECTION LABELS

我只对“SECTION LABELS”中包含的行感兴趣。我想:

  • 将 M1:NET 更改为 M1,将 M2:NET 更改为 M2
  • 如果最后一个元素是A或B,将A或B之前的数字从2改为3
  • 如果最后一个元素是其他元素,将数字(最后一个但一个)从 2 更改为 6
  • 如果 lab M1:NET 或 lab M1 之后的数字是 0 0 0 0,那么我不想更改任何内容。
  • 文件的其余内容保持不变

所以输出看起来像:

*Other text*
.....
.....
.....
SECTION LABELS {
lab M1 0 0 0 0 3 1 bot
lab M2 0 0 0 0 3 1 top
} SECTION LABELS

*Other text*
......
......
......
SECTION LABELS {
lab M1 5207 12261 5207 12261 0 3 A
lab M2 6880 5370 6880 5370 0 3 B
lab M1 3454 5386 3454 5386 0 6 alpha
lab M2 3454 5386 3454 5386 0 6 beta
} SECTION LABELS

最佳答案

您可以使用范围作为模式,然后对介于(含)之间的文本进行操作。供您输入:

awk '/^SECTION LABELS {/,/} SECTION LABELS/{
    sub(":NET","")
    if ($8 && !/M1 0 0 0 0/) $8 = ($NF ~ /^[AB]$/) ? 3 : 6 
}1' file.txt

注意: (1) 如果“SECTION LABELS”中的单词超过 7 个,则需要调整“if”部分(我认为这只是一个示例)。您可以将 '$8' 更改为 '$9' 或 $9 != ""等以跳过标题和结尾。

(2) 如果 A、B 是字符串而不是字符,则需要将正则表达式从 ^[AB]$ 更改为 ^(A|B)$

(3) 如果您还想保持 M2 0 0 0 0 不变,则将 !/M1 0 0 0 0/更改为 !/\<0 0 0 0\>/其中 '\<' 和 '\>' 是正则表达式中的单词边界。

关于linux - 使用 sed/awk 命令找到模式后修改文本文件的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25649656/

相关文章:

linux - Xtst 和 usleep

linux - gpg加密和解密

c - 多线程 epoll

linux - ssh通行证安全吗?

awk 按多列分组并使用非主键打印最大值

python - raspbian 自定义守护进程手动启动但不启动

bash - 如何制作 ls |不那么丰富多彩?

awk - 使用 awk gsub 替换 CSV 文件一列中的字符

bash - 如何使用 find 和 awk 提取文件名的一部分

c - 当文件路径中有空格时,如何使用 "system()"执行 bash 脚本?