50、高级sed编辑器使用指南

高级sed编辑器使用指南

1. 保留空间(Holding Space)

在sed编辑器处理命令时,模式空间(pattern space)是一个活跃的缓冲区,用于存储正在检查的文本。不过,sed编辑器还有另一个缓冲区,即保留空间(hold space)。保留空间可用于临时保存文本行,以便在处理模式空间中的其他行时使用。与保留空间操作相关的五个命令如下表所示:

命令 描述
h 将模式空间复制到保留空间
H 将模式空间追加到保留空间
g 将保留空间复制到模式空间
G 将保留空间追加到模式空间
x 交换模式空间和保留空间的内容

下面是一个简单的示例,展示了如何使用 h g 命令在sed编辑器的缓冲区之间来回移动数据:

$ cat data2.txt
Header Line
First Data Line
Second Data Line
End of Data Lines
$
$ sed -n '/First/ {
> h ; p ;
> n ; p ;
> g ; p }
> ' data2.txt
First Data Line
Second Data Line
First Data Line
$

具体步骤如下:
1. sed脚本使用正则表达式过滤包含单词 First 的行。
2. 当包含 First 的行出现时, h 命令将模式空间中的行复制到保留空间,此时模式空间和保留空间的数据相同。
3. p 命令打印模式空间的内容(即 First Data Line )。
4. n 命令获取数据流中的下一行( Second Data Line )并放入模式空间,此时模式空间和保留空间的数据不同。
5. p 命令打印模式空间的内容( Second Data Line )。
6. g 命令将保留空间的内容( First Data Line )放回模式空间,替换当前文本,此时模式空间和保留空间的数据再次相同。
7. p 命令打印模式空间的当前内容( First Data Line )。

如果去掉第一个 p 命令,就可以按相反顺序输出这两行:

$ sed -n '/First/ {
> h ;
> n ; p
> g ; p }
> ' data2.txt
Second Data Line
First Data Line
$
2. 否定命令(Negating a Command)

感叹号( ! )命令用于否定一个命令。也就是说,在正常情况下会激活的命令,使用 ! 后将不会被激活。例如:

$ sed -n '/Header/!p' data2.txt
First Data Line
Second Data Line
End of Data Lines
$

正常的 p 命令只会打印 data2 文件中包含单词 Header 的行。添加感叹号后,情况相反,文件中除了包含 Header 的行之外的所有行都会被打印。

感叹号在一些应用中非常有用。例如,在处理数据流的最后一行时,某些sed命令可能无法正常工作,因为没有后续行。可以使用感叹号来解决这个问题:

$ cat data4.txt
On Tuesday, the Linux System
Admin group meeting will be held.
All System Admins should attend.
$
$ sed 'N;
> s/System\nAdmin/DevOps\nEngineer/
> s/System Admin/DevOps Engineer/
> ' data4.txt
On Tuesday, the Linux DevOps
Engineer group meeting will be held.
All System Admins should attend.
$
$ sed '$!N;
> s/System\nAdmin/DevOps\nEngineer/
> s/System Admin/DevOps Engineer/
> ' data4.txt
On Tuesday, the Linux DevOps
Engineer group meeting will be held.
All DevOps Engineers should attend.
$

在这个例子中,感叹号与 N 命令和美元符号( $ )特殊地址一起使用。美元符号表示数据流中的最后一行,所以当sed编辑器到达最后一行时,不会执行 N 命令,但对于其他行,会执行该命令。

利用这个技术,可以反转数据流中文本行的顺序。具体步骤如下:
1. 将文本行放入模式空间。
2. 将模式空间中的行复制到保留空间。
3. 将下一行文本放入模式空间。
4. 将保留空间追加到模式空间。
5. 将模式空间中的所有内容复制到保留空间。
6. 重复步骤3到5,直到将所有行以相反顺序放入保留空间。
7. 检索并打印这些行。

graph TD;
    A[文本行放入模式空间] --> B[复制到保留空间];
    B --> C[放入下一行到模式空间];
    C --> D[追加保留空间到模式空间];
    D --> E[复制模式空间到保留空间];
    E --> C;
    E --> F{是否处理完所有行};
    F -- 是 --> G[打印结果];
    F -- 否 --> C;

为了实现这个功能,需要使用以下命令:
- 1!G :避免将保留空间追加到第一行。
- h :将新的模式空间复制到保留空间。
- $p :当到达数据流的最后一行时,打印结果。

测试示例如下:

$ cat data2.txt
Header Line
First Data Line
Second Data Line
End of Data Lines
$
$ sed -n '{1!G ; h ; $p }' data2.txt
End of Data Lines
Second Data Line
First Data Line
Header Line
$
3. 改变流程(Changing the Flow)
3.1 分支(Branching)

sed编辑器提供了一种基于地址、地址模式或地址范围来否定整个命令部分的方法,从而只对数据流中的特定子集执行一组命令。分支( b )命令的格式如下:

[address]b [label]
  • address 参数确定触发分支命令的数据行。
  • label 参数定义脚本中要分支到的位置。如果没有 label 参数,分支命令将跳过触发分支的数据行,继续处理其他文本行。

下面是一个使用地址参数但没有标签的分支命令示例:

$ cat data2.txt
Header Line
First Data Line
Second Data Line
End of Data Lines
$
$ sed '{2,3b ;
> s/Line/Replacement/}
> ' data2.txt
Header Replacement
First Data Line
Second Data Line
End of Data Replacements
$

分支命令跳过了数据流中第二行和第三行的替换命令。

也可以定义一个标签,让分支命令跳转到该位置。标签以冒号开头,长度最多为七个字符。例如:

$ sed '{/First/b jump1 ;
> s/Line/Replacement/
> :jump1
> s/Line/Jump Replacement/}
> ' data2.txt
Header Replacement
First Data Jump Replacement
Second Data Replacement
End of Data Replacements
$

如果行中出现匹配文本 First ,分支命令将跳转到标有 jump1 的脚本行。如果分支命令的地址不匹配,sed编辑器将继续处理脚本中的命令。

还可以分支到脚本中较早出现的标签,从而创建循环效果:

$ echo "This, is, a, test, to, remove, commas." |
> sed -n '{
> :start
> s/,//1p
> b start
> }'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
^C
$

为了防止出现无限循环,可以为分支命令指定一个地址模式。例如:

$ echo "This, is, a, test, to, remove, commas." |
> sed -n '{
> :start
> s/,//1p
> /,/b start
> }'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
$
3.2 测试(Testing)

测试( t )命令也用于修改sed编辑器脚本的流程。与分支命令不同, t 命令根据前面替换命令的结果跳转到标签。如果替换命令成功匹配并替换了模式,测试命令将分支到指定的标签;如果替换命令未匹配指定模式,测试命令将不分支。

测试命令的格式与分支命令相同:

[address]t [label]

如果不指定标签,当测试成功时,sed将跳转到脚本命令的末尾。

下面是一个使用测试命令的示例:

$ sed '{s/First/Matched/ ; t
> s/Line/Replacement/}
> ' data2.txt
Header Replacement
Matched Data Line
Second Data Replacement
End of Data Replacements
$

第一个替换命令查找模式文本 First 。如果匹配成功,替换文本,测试命令将跳过第二个替换命令;如果未匹配,将处理第二个替换命令。

使用测试命令可以改进之前使用分支命令的循环:

$ echo "This, is, a, test, to, remove, commas." |
> sed -n '{
> :start
> s/,//1p
> t start
> }'
This is, a, test, to, remove, commas.
This is a, test, to, remove, commas.
This is a test, to, remove, commas.
This is a test to, remove, commas.
This is a test to remove, commas.
This is a test to remove commas.
$

当没有更多逗号需要替换时,测试命令将不再分支,处理结束。

4. 通过模式替换(Replacing via a Pattern)
4.1 使用通配符替换的问题

在sed命令中使用模式替换数据流中的文本时,如果使用通配符,可能会遇到一些问题。例如:

$ echo "The cat sleeps in his hat." |
> sed 's/.at/".at"/g'
The ".at" sleeps in his ".at".
$

替换字符串使用了点通配符来匹配任何以“at”结尾的字母,但替换字符串没有匹配到匹配单词的通配符值。

4.2 使用&符号

sed编辑器提供了一个解决方案,即使用&符号来表示替换命令中匹配的模式。无论什么文本匹配了定义的模式,都可以在替换模式中使用&符号来引用它。例如:

$ echo "The cat sleeps in his hat." |
> sed 's/.at/"&"/g'
The "cat" sleeps in his "hat".
$
4.3 替换单个单词

&符号会检索替换命令中指定模式匹配的整个字符串。有时,你可能只想检索字符串的一个子集。sed编辑器使用括号来定义替换模式中的子字符串组件,然后可以在替换模式中使用特殊字符来引用每个子字符串组件。替换字符由反斜杠和数字组成,数字表示子字符串组件的位置。例如:

$ echo "The Guide to Programming" |
> sed '
> s/\(Guide to\) Programming/\1 DevOps/'
The Guide to DevOps
$

这个替换命令使用括号将 Guide to 标识为子字符串组件,然后在替换模式中使用 \1 来引用它。

再看一个例子:

$ echo "That furry cat is pretty." |
> sed 's/furry \(.at\)/\1/'
That cat is pretty.
$
$ echo "That furry hat is pretty." |
> sed 's/furry \(.at\)/\1/'
That hat is pretty.
$

在这种情况下,不能使用&符号,因为它会替换整个匹配的模式。子字符串组件提供了解决方案,允许你选择模式的哪一部分作为替换模式。

高级sed编辑器使用指南

5. 其他实用技巧总结

在使用sed编辑器时,除了前面介绍的保留空间、否定命令、改变流程和模式替换等技巧外,还有一些其他实用的要点需要注意。

5.1 命令组合的灵活性

sed允许将多个命令组合在一起使用,以实现更复杂的文本处理。例如,结合分支和替换命令,可以根据不同的条件对文本进行不同的处理。以下是一个示例:

$ cat data3.txt
Apple
Banana
Cherry
Date
$
$ sed '{/Banana/b special ; s/[a-zA-Z]*/& Fruit/ ; :special ; s/[a-zA-Z]*/& Special Fruit/ }' data3.txt
Apple Fruit
Banana Special Fruit
Cherry Fruit
Date Fruit
$

在这个例子中,如果文本行包含 Banana ,则跳转到 special 标签处进行特殊处理,否则进行普通的替换操作。

5.2 利用注释提高脚本可读性

在编写复杂的sed脚本时,可以使用注释来提高脚本的可读性。虽然sed本身没有专门的注释语法,但可以通过在脚本中添加不影响命令执行的字符来模拟注释。例如:

$ sed '{
# 查找包含Apple的行
/Apple/ {
    # 将其替换为Apple Delicious
    s/Apple/Apple Delicious/
}
# 对其他行进行普通替换
s/[a-zA-Z]*/& Generic/
}' data3.txt

这里使用 # 开头的行作为注释,帮助理解脚本的逻辑。

6. 实际应用场景分析

了解了sed的各种高级技巧后,我们来看一些实际的应用场景。

6.1 日志文件处理

在处理日志文件时,可能需要过滤掉一些无用的信息,提取关键数据。例如,有一个日志文件 log.txt ,内容如下:

[2024-01-01 10:00:00] INFO: User logged in: John
[2024-01-01 10:01:00] DEBUG: Some debug message
[2024-01-01 10:02:00] INFO: User logged out: John

如果我们只关心用户登录和退出的信息,可以使用sed进行过滤:

$ sed -n '/INFO: User/p' log.txt
[2024-01-01 10:00:00] INFO: User logged in: John
[2024-01-01 10:02:00] INFO: User logged out: John
$

还可以进一步提取用户名:

$ sed -n '/INFO: User/ s/.*: //p' log.txt
John
John
$
6.2 配置文件修改

在修改配置文件时,sed可以快速定位并修改特定的配置项。例如,有一个配置文件 config.ini ,内容如下:

[database]
host = localhost
port = 3306
username = root
password = secret

如果要将数据库主机修改为 new_host ,可以使用以下命令:

$ sed 's/host = .*/host = new_host/' config.ini
[database]
host = new_host
port = 3306
username = root
password = secret
$
7. 性能优化建议

在处理大量数据时,sed的性能可能会成为一个问题。以下是一些性能优化的建议:

7.1 减少不必要的命令

尽量避免在脚本中使用过多的命令,尤其是一些复杂的正则表达式和循环。例如,如果只需要简单的替换操作,就不要使用复杂的分支和测试命令。

7.2 批量处理

如果需要处理多个文件,可以将多个文件一起传递给sed,而不是一个一个地处理。例如:

$ sed -i 's/old_text/new_text/' file1.txt file2.txt file3.txt

这里的 -i 选项表示直接在文件中进行替换。

7.3 合理使用正则表达式

正则表达式的复杂度会影响sed的性能。尽量使用简单的正则表达式,避免使用过于复杂的模式匹配。

总结

sed编辑器是一个强大的文本处理工具,通过掌握其高级技巧,如保留空间的使用、否定命令、改变流程、模式替换等,可以实现复杂的文本处理任务。在实际应用中,要根据具体的需求选择合适的技巧,并注意性能优化。通过不断的实践和总结,你将能够熟练运用sed编辑器,提高工作效率。

技巧 描述 示例
保留空间 用于临时保存文本行,通过特定命令在模式空间和保留空间之间移动数据 sed -n '/First/ { h ; p ; n ; p ; g ; p }' data2.txt
否定命令 使用 ! 否定命令的执行 sed -n '/Header/!p' data2.txt
分支 根据地址或模式跳转到脚本中的指定位置 sed '{/First/b jump1 ; s/Line/Replacement/ ; :jump1 ; s/Line/Jump Replacement/}' data2.txt
测试 根据替换命令的结果跳转到指定标签 sed '{s/First/Matched/ ; t ; s/Line/Replacement/}' data2.txt
模式替换 使用 & 引用匹配的模式,使用括号定义子字符串组件 sed 's/.at/"&"/g' sed 's/\(Guide to\) Programming/\1 DevOps/'

通过这些技巧和应用场景的介绍,希望你能更好地掌握sed编辑器,在日常的文本处理工作中发挥其强大的功能。

【无人机】基于改进粒子群算法的无人机路径规划研究[和遗传算法、粒子群算法进行比较](Matlab代码实现)内容概要:本文围绕基于改进粒子群算法的无人机路径规划展开研究,重点探讨了在复杂环境中利用改进粒子群算法(PSO)实现无人机三维路径规划的方法,并将其与遗传算法(GA)、标准粒子群算法等传统优化算法进行对比分析。研究内容涵盖路径规划的多目标优化、避障策略、航路点约束以及算法收敛性和寻优能力的评估,所有实验均通过Matlab代码实现,提供了完整的仿真验证流程。文章还提到了多种智能优化算法在无人机路径规划中的应用比较,突出了改进PSO在收敛速度和全局寻优方面的优势。; 适合人群:具备一定Matlab编程基础和优化算法知识的研究生、科研人员及从事无人机路径规划、智能优化算法研究的相关技术人员。; 使用场景及目标:①用于无人机在复杂地形或动态环境下的三维路径规划仿真研究;②比较不同智能优化算法(如PSO、GA、蚁群算法、RRT等)在路径规划中的性能差异;③为多目标优化问题提供算法选型和改进思路。; 阅读建议:建议读者结合文中提供的Matlab代码进行实践操作,重点关注算法的参数设置、适应度函数设计及路径约束处理方式,同时可参考文中提到的多种算法对比思路,拓展到其他智能优化算法的研究与改进中。
标题中的"EthernetIP-master.zip"压缩文档涉及工业自动化领域的以太网通信协议EtherNet/IP。该协议由罗克韦尔自动化公司基于TCP/IP技术架构开发,已广泛应用于ControlLogix系列控制设备。该压缩包内可能封装了协议实现代码、技术文档或测试工具等核心组件。 根据描述信息判断,该资源主要用于验证EtherNet/IP通信功能,可能包含测试用例、参数配置模板及故障诊断方案。标签系统通过多种拼写形式强化了协议主题标识,其中"swimo6q"字段需结合具体应用场景才能准确定义其技术含义。 从文件结构分析,该压缩包采用主分支命名规范,符合开源项目管理的基本特征。解压后预期可获取以下技术资料: 1. 项目说明文档:阐述开发目标、环境配置要求及授权条款 2. 核心算法源码:采用工业级编程语言实现的通信协议栈 3. 参数配置文件:预设网络地址、通信端口等连接参数 4. 自动化测试套件:包含协议一致性验证和性能基准测试 5. 技术参考手册:详细说明API接口规范与集成方法 6. 应用示范程序:展示设备数据交换的标准流程 7. 工程构建脚本:支持跨平台编译和部署流程 8. 法律声明文件:明确知识产权归属及使用限制 该测试平台可用于构建协议仿真环境,验证工业控制器与现场设备间的数据交互可靠性。在正式部署前开展此类测试,能够有效识别系统兼容性问题,提升工程实施质量。建议用户在解压文件后优先查阅许可协议,严格遵循技术文档的操作指引,同时需具备EtherNet/IP协议栈的基础知识以深入理解通信机制。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值