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

时间:2014-09-03 16:47:45

标签: 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
  • 如果实验室M1:NET或实验室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

2 个答案:

答案 0 :(得分:2)

以下是帮助您入门的一些内容:

awk '/SECTION LABELS/ {f=!f} f && /NET/ && !/lab M1(:NET)* 0 0 0 0/ {split($2,a,":");$2=a[1];if ($NF~/\<[A|B]\>/) $(NF-1)=3; else $(NF-1)=6}1' t
*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

答案 1 :(得分:2)

您可以使用范围作为模式,然后对两者之间的文本进行操作(包括)。供您参考:

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 /到!/ \&lt; 0 0 0 0 \&gt; /其中'\&lt;'和'\&gt;'是正则表达式中的单词边界。