0

我正在尝试编写一个 bash 脚本,该脚本使用 sed 修改配置文件中不包含特定字符串的行。举例说明,我可以...

/some/file/path1 ipAddress1/subnetMask(rw,sync,no_root_squash)
/some/file/path2 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1)
/some/file/path3 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=0)
/some/file/path4 ipAddress2/subnetMask(rw,sync,no_root_squash,anongid=-1)
/some/file/path5 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)

而且我希望更改每一行的括号列表,使其包含字符串anonuid=-1anongid=-1在其括号内...

/some/file/path1 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path2 ipAddress1/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path3 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)
/some/file/path4 ipAddress2/subnetMask(rw,sync,no_root_squash,anongid=-1,anonuid=-1)
/some/file/path5 ipAddress2/subnetMask(rw,sync,no_root_squash,anonuid=-1,anongid=-1)

从示例中可以看出,括号中可能已经存在anonuidanongid,但有可能原始括号列表有一个字符串而没有另一个字符串(第 2、3 和 4 行),列表都没有(第 1 行) ),列表都已正确设置(第 5 行),甚至其中一个或两个设置不正确(第 3 行)。当其中一个anonuidanongid设置为 以外的值-1时,必须将其更改为-1(第 3 行)的正确值。

使用 sed 编辑我的配置文件的最佳方法是什么,anonuid=-1并且anongid=-1包含在每行的括号列表中,当然用逗号分隔符分隔?

4

3 回答 3

2

我认为这可以满足您的要求:

sed -e '/anonuid/{s/anonuid=[-0-9]*/anonuid=-1/;b gid;};s/)$/,anonuid=-1)/;:gid;/anongid/{s/anongid=[-0-9]*/anongid=-1/;b;};s/)$/,anongid=-1)/'

基本上,它有两个几乎相同的部分,第一个处理 anonuid 和第二个 anongid,每个部分都有一些逻辑来决定是否需要替换或添加适当的值。(无需检查该值是否已经正确,这只会使事情复杂化,而不会改变结果。)

于 2013-04-08T18:05:26.227 回答
1

您可以使用 sed 指定您感兴趣的行:

$ sed '/anonuid=..*,anongid=..*)$/!p' $file

以上将打印 ( p) 所有与两个斜杠之间的正则表达式不匹配的行。我使用!. _ 这样,您就不会将行与它们anaonuidanongid它们都匹配。

现在,您可以处理不匹配的行并使用 seds命令编辑这些行:

$ sed '/anonuid=..*,anongid=..*)$/!s/from/to/`

操作可能相当复杂,您可能会传递多个sed命令以使一切正常

但是,如果字符串no_root_squash出现在您要更改的每一行中,为什么不采取简单的方法:

$ sed 's/no_root_squash.*$/no_root_squash,anonuid=-1,anongid=-1)/' $file

这是在寻找那个no_root_squash字符串,并用你想要的文本替换从那个字符串到行尾的所有内容。是否有您触摸的线条不需要编辑?是的,但你并没有真正改变这些线路。您基本上是/no_root_squash,anonuid=-1,anongid=-1)用相同的/no_root_squash,anonuid=-1,anongid=-1).

即使它正在替换不需要替换的文本,这可能会更快,因为正在进行的处理较少。另外,将来更容易理解和支持。

回复

谢谢大卫!是的,我正在考虑走那条路,但我不想 100% 依赖包含 no_root_squash 的每一行。我当前的配置文件仅以该字符串结尾,但我不能 100% 确定该字段不会有所不同。你认为有没有办法改变它,所以它只是从最后一个不包含 anonuid=-1 或 anongid=-1 的字符串的末尾开始覆盖?

你能保证每一行都有什么?

您也许可以做一个捕获组:

 sed 's/\(sync,[^,)]*\).*/\1,anonuid=-1,anongid=-1)/' $file

\(..\)是一个捕获组。它基本上捕获了匹配正则表达式的那部分,然后允许您通过\1. 我正在从单词sync中捕获一组字符,不包括逗号或右括号。然后,我将附加捕获组、逗号以及您的匿名 uid 和 gid。

那会奏效吗?

于 2013-04-08T18:32:14.390 回答
0

也许我过于简单化了:

sed 's/anonuid=[-0-9]*[^)]//g;s/anongid=[-0-9]*[^)]//g;s/[)]/anonuid=-1,anongid=-1)/g' test.txt > test3.txt

anonuid这只是删除or的任何当前实例anongid并将字符串添加 "anonuid=-1,anongid=-1"到括号中

于 2013-04-08T19:52:43.573 回答