pow*_*ash 4 sed text-processing
我正在尝试编写一个脚本来更改 dovecot 用户数据库中的用户密码,但我无法理解如何用sed.
例如,请检查这一行(这是来自 dovecot userdb 的部分):
123@example.com:{SHA512-CRYPT}$6$0vthg.LubtSCxRRK$MdTKNQ2Vk8ZW3XQXNXStt9rfr6fNa??XqPvZ0o9WJ8mW8y9ozE1pi8dYM8oQzwWa8ESGzEmJO6yT/tgi3ZEqAiE0:::
abc@example.com:{SHA512-CRYPT}$6$0vthg.LubtSCxRRK$MdTKNQ2Vk8ZW3XQXNXStt9rfr6fNa??XqPvZ0o9WJ8mW8y9ozE1pi8dYM8oQzwWa8ESGzEmJO6yT/tgi3ZEqAiE0:::
Run Code Online (Sandbox Code Playgroud)
如何仅针对用户“123@example.com”而不是用户“abc@example.com”使用sed替换以“{SHA512-CRYPT}”开头的“:”分隔符之间的字符串?
也许:
sed 's/\(\(^\|:\)123@example\.com:\)\([^:]\+\)/\1foo/'
Run Code Online (Sandbox Code Playgroud)
鉴于值中没有转义分隔符。
sed 's/\(\(^\|:\)123@example\.com:\)\([^:]\+\)/\1foo/'
| | | | | | | |
| | | | | | | +----- H. End of sub.
| | | | | | +------- G. Sub string
| | | | | +---------- F. Match Group 1.
| | | | +------------ E. End of Group 3.
| | | +------------------ D. Group 3.
| | +----------------------------------- C. User
| +--------------------------------------------- B. Prefix Group 2.
+--------------------------------------------------- A. Substitute
Run Code Online (Sandbox Code Playgroud)
A: s/ 替换命令。B: (^|:)以行首或分隔符:、组 2、匹配组 1 的一部分开始。C: 要匹配的用户,匹配组 1 的一部分。D: ([^:]+)要删除的部分,直到:. 第 3 组的一部分。直到下一个分隔符的所有内容。也许应该是\(:\|$\),但它应该以:它结束就足够了。E: \) 结束删除分组。 F: \1 放回匹配组 1。用户 + 分隔符。G: foo 什么都将作为地穴插入。H: /结束这一切。可选地是/g全局的,但假设它只是一次。你可以在这里替换地址 -
sed '/^123@example.com:{SHA512-CRYPT}/s/{[^:]*/REPLACE/'
Run Code Online (Sandbox Code Playgroud)
这里s///替换命令是/regxp/地址的函数,因此s///除非该行首先匹配其父地址,否则甚至不会尝试替换。
或者只带一个s///:
sed 's/^\(123@example.com:\){SHA512-CRYPT}[^:]*/\1REPLACE/'
Run Code Online (Sandbox Code Playgroud)
或者仅当 123 不紧跟冒号时才锚定到行首:
sed 's/^\(\(.*:\)*123@example.com:\){SHA512-CRYPT}[^:]*/\1REPLACE/'
Run Code Online (Sandbox Code Playgroud)
虽然我当然对复杂的子表达式并不陌生,但在这种情况下,这种事情是不必要的——我通常更喜欢地址形式,当我能得到它时——我发现它更容易阅读,更有效,而且完全可移植。诚然,乍一看,我似乎高估了这里固有的复杂性。
同样,您也可以拆分反向引用和实际替换,例如:
sed -e '
/^\(123@example.com:\){SHA512-CRYPT}[^:]*/!b
s//\1REPLACE/
#other commands that can be sure to affect only a line matching the 1st address'
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,地址通过b为任何!不匹配的行退出脚本来验证匹配,但如果任何行通过其匹配测试,它也会在保存变量位以\1供下一个s///替换时执行双重任务。此外,所有后续命令也只能在匹配初始地址的行上执行。
当然,还有一种不太最终的形式,它用花括号指定了一个匹配函数上下文:
sed -e '
/^123@example.com:{SHA512-CRYPT}/{
s/{[^:]*/REPLACE/
#other function commands
};/other match function/{
#still more commands...
}'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3510 次 |
| 最近记录: |