regex - Bash SED 字符串替换 - 删除正则表达式前后的字符
问题描述
我有这个简单的 bash (3) 脚本来扫描目录中的所有文件,并用新的 CSS 类替换一些旧的 CSS 类。
export LC_ALL=C
ARRAY=(
"a-oldclass:new-class"
"m-oldclass:new-class"
)
for className in "${ARRAY[@]}" ; do
REGEX=[^a-zA-Z0-9]${className%%:*}[^a-zA-Z0-9]
CHANGE="s/${REGEX}/${className##*:}/g"
find src -type f -exec sed -i '' "${CHANGE}" '{}' +
done
它是键:值对和正则表达式的组合。问题是它还会删除匹配模式之前和之后的特殊字符,例如:
class="a-oldclass" => class=new-class (Quotes are gone)
class=" a-oldclass " => class="new-class" (spaces are gone)
我需要这个结果:
class="a-oldclass m-oldclass" => class="new-class new-class".
[^a-zA-Z0-9]
有必要避免这种情况:我想替换a-oldclass
为new-class
,但我不想触摸 class data-oldclass
。由于此字符串包含a-oldclass
它将被修改。所以[^a-zA-Z0-9]
我排除了这种情况。
解决方案
这应该是正则表达式:
REGEX='\([^a-zA-Z0-9]\)'"${className%%:*}"'\([^a-zA-Z0-9]\)'
CHANGE="s/${REGEX}/\1${className##*:}\2/g"
这使用\( \)
和\1 \2
重现类名之前和之后的匹配。
此外,我建议不要使用全大写变量,因为它们可能与 BASH 默认变量冲突。
如果您还需要匹配换行符终止的字符串,您可以添加
REGEX='\([^a-zA-Z0-9]\)'"${className%%:*}"'\([^a-zA-Z0-9]\)'
CHANGE="s/${REGEX}/\1${className##*:}\2/g"
REGEXNL='\([^a-zA-Z0-9]\)'"${className%%:*}"'$'
CHANGENL="s/${REGEXNL}/\1${className##*:}/g"
并将sed
命令更改为
sed -i -e "${CHANGE}" -e "${CHANGENL}"
我敢打赌,有一个更优雅的解决方案,但这sed
经受住了-posix
考验。
推荐阅读
- ajax - 在烧瓶应用程序中使用 get_json() 解码收到的 PUT 数据时出错
- rabbitmq - 如何使用启用了 LDAP 的 RabbitMQ 配置 NServiceBus
- jquery - 如何检查
jquery中的值?
- html - HTML中的模式表
- javascript - 如何在查找中执行函数或将数据保存在变量中?
- spring - 在测试服务器中出现错误 504 但不是在本地
- javascript - 调用 jquery .change() 函数时出现太多不需要的结果
- java - 在Jtable上插入ImageIcon,只显示图片路径
- docker - Docker 主机网络会破坏应用程序的可移植性吗?
- node.js - 如何获取存储桶中的所有对象列表,包括来自 S3 存储桶的单个请求中的标签