在编程中我们经常会看到使用常用表达。
最常见的形式之一是:
newText = text.replace( /regex/, 'replacementString' )
如果标准输入是text
并且标准输出是newText
,与上面的代码等效的 bash 是什么?
答案1
答案2
最直接的答案是sed的s
命令。您需要将正则表达式语法转换为基本正则表达式,并且替换将连续应用于每一行。您可以使用\1
through\9
来引用原始字符串中带括号的组。添加g
修饰符以替换所有出现的情况;否则仅替换第一个出现的位置。
sed -e 's/basic regexp/replacement string/g'
更灵活的实用程序是awk。默认情况下,它也逐行处理其输入,但您可以使用以下命令更改记录分隔符-vRS=…
(标准 awk 需要单个字符,或者空值表示两个或多个换行符;Gawk(GNU 版本)接受正则表达式)。该sub
函数执行单个替换,并gsub
替换所有出现的情况。替换字符串按字面解释,除了\
和&
;如果要引用括号内的组,可以使用match
和subtring
函数。
awk '{gsub(/regexp/, "replacement string")}'
Bash 内置了对正则表达式匹配的支持:[[ text =~ regexp ]]
.您可以使用数组中存储的匹配子字符串构造替换文本BASH_REMATCH
。使用read
或cat
获取输入并printf
发出输出。以下伪代码执行多次替换(警告,未经测试;代码应该像往常一样从左到右执行多次替换,我希望我做对了)。
# The end marker must not have a prefix that is a suffix of a match of the regexp,
# and must not start or end with a newline
end_marker='EOF'
text=$(cat; echo "$end_marker")
while [[ $text =~ regexp(.*)$ ]]; then
printf %s%s "${text%"$BASH_REMATCH[0]"}" "replacement string"
text=$BASH_REMATCH[$#BASH_REMATCH]
fi
done
printf %s "${text%"$end_marker"}"
(解释几句:结束标记是为了避免尾随换行符被命令替换删除。${text%"$BASH_REMATCH[0]"}
提取匹配之前的文本部分。请注意,我们不能^(.*)
在正则表达式的开头使用,否则我们' d 获取最后一个匹配项而不是第一个匹配项。匹配后,我们迭代后缀,最后打印不匹配的剩余部分,减去结束标记。)
如果您对通配符匹配和有限的替换文本功能感到满意,bash 还具有${variable/pattern/replacement}
.将第一个斜杠加倍以替换所有出现的斜杠。如果extglob
设置了该选项,模式确实具有正则表达式的功能(但具有不寻常的语法) 。
答案3
man sed
sed s/regex/replacementString/g
答案4
您可以使用sed
和之类的工具awk
,但在我看来,它们非常过时,仅对狭义定义的任务有用。
更好的选择是将 STDIN 重定向到 Perl 单行代码或脚本。 perl 的正则表达式支持非常好,以至于大多数其他语言现在都支持与它们的某些兼容性。甚至还有a2p
工具s2p
可以将 sed 和 awk 直接转换为 Perl。使用 perl 允许您使用整个 CPAN 来帮助您解决问题。
如果您不喜欢 perl,您可以使用 python 来实现类似的功能。