使用 sed 匹配字符串但不删除超过任意数量的特定字符然后是字符的任何内容
use sed to match on string but not remove anything past any number of specific characters then a character
这是一个名为“config_file.txt”的示例文件:
setting01 = 0 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
我需要替换每个设置但设置后不影响任何东西。这意味着不要删除设置后的任何白色 space、“#”和“#”之后的任何内容。
我尝试了以下方法来替换“setting01”
sed -i "s/setting01\ =\ .*#/setting01\ = 1/g" conf_file.txt
然而结果是:
setting01 = 1 Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
当我想要这个时:
setting01 = 1 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
我怎样才能做到这一点?
您可以使用
sed -i -E 's/(setting01 = )("[^"]*"|[^[:space:]]+)//g' conf_file.txt
详情:
-E
- 启用 POSIX ERE 正则表达式语法
(setting01 = )
- 第 1 组:setting01 =
("[^"]*"|[^[:space:]]+)
- 第 2 组:
"[^"]*"
- "
,然后 "
以外的零个或多个字符,然后是 "
|
- 或
[^[:space:]]+
- 一个或多个非空白字符
</code> 将匹配替换为第 1 组值和 <code>1
(因为在 POSIX 正则表达式中不能超过 </code> 个反向引用,<code>
未被 sed
解析为第 11 个反向引用)。
参见 online demo:
#!/bin/bash
s='setting01 = 0 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05'
sed -E 's/(setting01 = )("[^"]*"|[^[:space:]]+)//g' <<< "$s"
输出:
setting01 = 1 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
这可能适合您 (GNU sed):
sed -E '/^(setting03 = )(\S+)/{s//\nXXX\n/
:a;ta;s/(\n.*\n *)[^ #]/ /;ta
:b;tb;s/\n(\S)(.*\n) /\n/;tb
s/\n#([^\n]*)$/ #/;s/\n//g;s/ +$//}' file
通过设置 -E
命令行选项打开扩展正则表达式。
替换 setting03
的值,在换行符前面加上另一个换行符和原始值(用作模板)。
用 spaces 替换模板,然后在其上叠加新值。
删除换行符,如果新值大于评论前的 spaces,附加一个额外的 space 将其与评论分开。
最后,如果原始行没有注释,请删除 space 个工件。
这是一个名为“config_file.txt”的示例文件:
setting01 = 0 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
我需要替换每个设置但设置后不影响任何东西。这意味着不要删除设置后的任何白色 space、“#”和“#”之后的任何内容。
我尝试了以下方法来替换“setting01”
sed -i "s/setting01\ =\ .*#/setting01\ = 1/g" conf_file.txt
然而结果是:
setting01 = 1 Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
当我想要这个时:
setting01 = 1 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
我怎样才能做到这一点?
您可以使用
sed -i -E 's/(setting01 = )("[^"]*"|[^[:space:]]+)//g' conf_file.txt
详情:
-E
- 启用 POSIX ERE 正则表达式语法(setting01 = )
- 第 1 组:setting01 =
("[^"]*"|[^[:space:]]+)
- 第 2 组:"[^"]*"
-"
,然后"
以外的零个或多个字符,然后是"
|
- 或[^[:space:]]+
- 一个或多个非空白字符
</code> 将匹配替换为第 1 组值和 <code>1
(因为在 POSIX 正则表达式中不能超过 </code> 个反向引用,<code>
未被 sed
解析为第 11 个反向引用)。
参见 online demo:
#!/bin/bash
s='setting01 = 0 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05'
sed -E 's/(setting01 = )("[^"]*"|[^[:space:]]+)//g' <<< "$s"
输出:
setting01 = 1 # Comment for setting 01
setting02 = 1 # Comment for setting 02
setting03 = "./folder" # Comment for setting 03
setting04 = "string" # Comment for setting 04
setting05 = 1 # Comment for setting 05
这可能适合您 (GNU sed):
sed -E '/^(setting03 = )(\S+)/{s//\nXXX\n/
:a;ta;s/(\n.*\n *)[^ #]/ /;ta
:b;tb;s/\n(\S)(.*\n) /\n/;tb
s/\n#([^\n]*)$/ #/;s/\n//g;s/ +$//}' file
通过设置 -E
命令行选项打开扩展正则表达式。
替换 setting03
的值,在换行符前面加上另一个换行符和原始值(用作模板)。
用 spaces 替换模板,然后在其上叠加新值。
删除换行符,如果新值大于评论前的 spaces,附加一个额外的 space 将其与评论分开。
最后,如果原始行没有注释,请删除 space 个工件。