我正在尝试编写一个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=-1
和anongid=-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)
从示例中可以看出,anonuid
和anongid
可能已存在于括号内,但原始括号列表可能有一个字符串而不是另一个字符串(第2行, 3和4),列表既没有(第1行),列表已经正确设置(第5行),或者甚至其中一个或两个都设置不正确(第3行)。如果anonuid
或anongid
设置为-1
以外的值,则必须将其更改为-1
的正确值(第3行)。
使用sed编辑配置文件的最佳方法是什么,anonuid=-1
和anongid=-1
包含在每行的括号列表中,当然用逗号分隔符分隔?
答案 0 :(得分: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,每个部分都有一些逻辑来决定是否需要替换或添加适当的值。 (它无需检查值是否已经正确,这会使事情变得复杂而不改变结果。)
答案 1 :(得分:1)
您可以使用sed指定您感兴趣的行:
$ sed '/anonuid=..*,anongid=..*)$/!p' $file
上面将打印(p
)所有与两个斜杠之间的正则表达式不匹配的行。我使用!
否定 表达式。这样,您就不会在其中与anaonuid
和anongid
匹配。
现在,您可以处理不匹配的行并使用sed s
命令编辑它们:
$ 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
捕获到一组不包括逗号或右括号的字符。然后,我附加了捕获组,一个逗号,以及你的anid uid和gid。
这会起作用吗?
答案 2 :(得分:0)
也许我过于简单化了:
sed 's/anonuid=[-0-9]*[^)]//g;s/anongid=[-0-9]*[^)]//g;s/[)]/anonuid=-1,anongid=-1)/g' test.txt > test3.txt
这会删除anonuid
或anongid
的所有当前实例并添加字符串
"anonuid=-1,anongid=-1"
加入括号