一、概述
我们可以借助 lineinfile 模块,确保”某一行文本”存在于指定的文件中,或者确保从文件中删除指定的”文本”(即确保指定的文本不存在于文件中),还可以根据正则表达式,替换”某一行文本”。
二、常用参数
- path参数 : 必须参数,指定要操作的文件。
- line参数 : 使用此参数指定文本内容。
- regexp参数 : 使用正则表达式匹配对应的行,当替换文本时,如果有多行文本都能被匹配,则只有最后面被匹配到的那行文本才会被替换,当删除文本时,如果有多行文本都能被匹配,这么这些行都会被删除。
- state参数: 当想要删除对应的文本时,需要将state参数的值设置为absent,absent为缺席之意,表示删除,state的默认值为present。
- backrefs参数: 默认情况下,当根据正则替换文本时,即使regexp参数中的正则存在分组,在line参数中也不能对正则中的分组进行引用,除非将backrefs参数的值设置为yes。backrefs=yes表示开启后向引用,这样,line参数中就能对regexp参数中的分组进行后向引用了,这样说不太容易明白,可以参考后面的示例命令理解。backrefs=yes除了能够开启后向引用功能,还有另一个作用,默认情况下,当使用正则表达式替换对应行时,如果正则没有匹配到任何的行,那么line对应的内容会被插入到文本的末尾,不过,如果使用了backrefs=yes,情况就不一样了,当使用正则表达式替换对应行时,同时设置了backrefs=yes,那么当正则没有匹配到任何的行时,则不会对文件进行任何操作,相当于保持原文件不变。
- insertafter参数: 借助insertafter参数可以将文本插入到“指定的行”之后,insertafter参数的值可以设置为EOF或者正则表达式,EOF为End Of File之意,表示插入到文档的末尾,默认情况下insertafter的值为EOF,如果将insertafter的值设置为正则表达式,表示将文本插入到匹配到正则的行之后,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。
- insertbefore参数: 借助insertbefore参数可以将文本插入到“指定的行”之前,insertbefore参数的值可以设置为BOF或者正则表达式,BOF为Begin Of File之意,表示插入到文档的开头,如果将insertbefore的值设置为正则表达式,表示将文本插入到匹配到正则的行之前,如果正则没有匹配到任何行,则插入到文件末尾,当使用backrefs参数时,此参数会被忽略。
- backup参数: 是否在修改文件之前对文件进行备份。
- create参数 : 当要操作的文件并不存在时,是否创建对应的文件。
三、示例
1、插入一行文本到 t2.txt 文件中,如指定的文本本来就存在于文件中,则不做任何操作,如不存在,默认在文件的末尾插入,如下命令表示确保 “aaa” 这行文本存在于 /root/t2.txt 文件中。
- 测试文件:
[root@CentOSA ~]# cat t2.txt
aaa
bbb
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt line="aaa" '
192.168.0.160 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": false,
"msg": ""
}
- 文件没有任何变化:
[root@CentOSA ~]# cat t2.txt
aaa
bbb
- 指定文件没有的内容:
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt line="ccc" '
192.168.0.160 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line added"
}
- 文件最后一行追加:
[root@CentOSA ~]# cat t2.txt
aaa
bbb
ccc
2、如下命令表示替换”某一行”,如有多行相同,则只有最后一个匹配正则的行才会被替换,被匹配行会被替换成 line 参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么 line 中的内容会被添加最后一行。
- 测试文件:
[root@CentOSA ~]# cat t2.txt
aaa
bbb
ccc
abc
[root@CentOSB ~]# cat t2.txt
AAA
bbb
ccc
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt regexp="^a" line="AAA" '
192.168.0.161 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
192.168.0.160 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
- 查看文件内容:
[root@CentOSA ~]# cat t2.txt
aaa
bbb
ccc
AAA 被替换后
[root@CentOSB ~]# cat t2.txt
AAA 被替换后
bbb
ccc
主机A替换最后一行,主机B替换第一行
3、如下命令表示替换”某一行”,如有多行相同,则只有最后一个匹配正则的行才会被替换,被匹配行会被替换成 line 参数指定的内容,但是如果指定的表达式没有匹配到任何一行,那么 line 中的内容会被添加最后一行。如果指定的表达式没有匹配到任何一行,那么则不对文件进行任何操作。
- 测试文件
[root@CentOSA ~]# cat t2.txt
aaa
abc
bbb
ccc
AAA
[root@CentOSB ~]# cat t2.txt
abc
aaa
a1
AAA
bbb
ccc
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt regexp="^a1" line="test" backrefs=yes '
192.168.0.160 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": false,
"msg": ""
}
192.168.0.161 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
[root@CentOSA ~]# cat t2.txt
aaa
abc
bbb
ccc
AAA
[root@CentOSB ~]# cat t2.txt
abc
aaa
test
AAA
bbb
ccc
只有主机B中a1开头被替换
4、根据 line 参数的内容删除行,如果文件中有多行都与 line 参数的内容相同,那么这些相同的行都会被删除。
- 测试文件:
[root@CentOSA ~]# cat t2.txt
aaa
abc
bbb
ccc
AAA
[root@CentOSB ~]# cat t2.txt
abc
aaa
test
AAA
bbb
ccc
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt line="bbb" state=absent'
192.168.0.160 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"found": 1,
"msg": "1 line(s) removed"
}
192.168.0.161 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"found": 1,
"msg": "1 line(s) removed"
}
[root@CentOSA ~]# cat t2.txt
aaa
abc
ccc
AAA
[root@CentOSB ~]# cat t2.txt
abc
aaa
test
AAA
ccc
所有主机t2.txt内容为bbb的行被删除
5、根据正则表达式删除对应行,如果有多行都满足正则表达式,那么所有匹配的行都会被删除。
- 测试文件:
[root@CentOSA ~]# cat t2.txt
aaa
abc
ccc
AAA
[root@CentOSB ~]# cat t2.txt
abc
aaa
test
AAA
ccc
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt regexp="^a" state=absent'
192.168.0.160 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"found": 2,
"msg": "2 line(s) removed"
}
192.168.0.161 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"found": 2,
"msg": "2 line(s) removed"
}
[root@CentOSA ~]# cat t2.txt
ccc
AAA
[root@CentOSB ~]# cat t2.txt
test
AAA
ccc
t2.txt文件中满足开头a的行全部删除
5、lineinfile 模块不支持后向引用。如果将 backrefs 设置为 yes,表示开启支持后向引用。使用如下命令,可以将 test 示例文件中的 “test test01” 替换成 “test0”,如果不设置 backrefs=yes,则不支持后向引用,那么 “test test01” 将被替换成 “\2”。
- 测试文件:
[root@CentOSA ~]# cat t2.txt
ccc
AAA
[root@CentOSB ~]# cat t2.txt
test test01
AAA
ccc
[root@Ansible ~]# ansible all -m lineinfile -a 'path=/root/t2.txt regexp="(t.{4}).*(t.{4})" line="\2" backrefs=yes'
192.168.0.160 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": false,
"msg": ""
}
192.168.0.161 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"backup": "",
"changed": true,
"msg": "line replaced"
}
[root@CentOSA ~]# cat t2.txt
ccc
AAA
[root@CentOSB ~]# cat t2.txt
test0
AAA
ccc