题
我正在编写一个 shell (bash) 脚本,并且正在尝试找出一种简单的方法来完成一项简单的任务。
我的变量中有一些字符串。我不知道这是否相关,但它可以包含空格、换行符,因为实际上这个字符串是整个文本文件的内容。
我想用其他内容替换最后一次出现的某个子字符串。也许我可以使用正则表达式来实现这一点,但有两个时刻让我感到困惑:
- 我需要从末尾开始匹配,而不是从头开始
- 我想要扫描的子字符串是固定的,而不是可变的。
解决方案
- 用于在开头截断:
${var#pattern}
- 在末尾截断
${var%pattern}
${var/pattern/repl}
用于一般更换
这些模式是 'filename' 样式扩展,最后一个可以使用前缀 #
或者 %
仅在开始或结束时(分别)匹配
这一切都在(长)bash 联机帮助页中。查看“参数扩展”章节。
其他提示
amn 这样的表达
s/match string here$/new string/
应该可以解决这个问题 - s 代表替换,/ 分解命令,$ 是行尾标记。您可以在 vi 中尝试一下,看看它是否满足您的需要。
我会查找 awk 或 sed 的手册页。
哈维尔的答案是特定于 shell 的,并不适用于所有 shell。
MrTelly 和 epochwolf 提到的 sed 答案是不完整的,应该如下所示:
MyString="stuff ttto be edittted"
NewString=`echo $MyString | sed -e 's/\(.*\)ttt\(.*\)/\1xxx\2/'`
这种方法不需要使用 $ 来标记结束的原因是第一个 '.*' 是贪婪的,并且会尝试尽可能多地收集,同时允许正则表达式的其余部分为真。
这个 sed 命令应该在任何使用的 shell 上下文中都能正常工作。
通常当我陷入 Sed 困境时我会使用这个页面,
不隶属于 StackOverflow