【问题标题】:How can I find and replace all forms of pow(var,2) with square(var)?如何用 square(var) 查找和替换所有形式的 pow(var,2)?
【发布时间】:2021-01-11 04:17:20
【问题描述】:

我想查找并用square(var) 替换当前目录的C++ 文件中出现的所有形式的pow(var,2)

我正在查看https://regexr.com/,但我仍然不确定如何将var 描述为正则表达式。复杂之处在于var 是任何符合以下事实的变量名称的占位符:

  1. 不包含空格
  2. 它以pow(,2) 为界
  3. 由大写字母[A-Z]、小写字母[a-z]组成, 和/或下划线字符_。 是否有规范的方法可以在 Linux 中进行这种重构?

使用最小工作示例更新 1:

输入:

pow(alpha,2) + pow(beta,2)
(3*pow(betaR_red,2))
2/pow(gammaBlue,3))
-pow(epsilon_gamma,2)+5

期望的输出:

square(alpha) + square(beta)
(3*square(betaR_red))
2/pow(gammaBlue,3))
-square(epsilon_gamma)+5

更新 2:

这里是后续question 的链接,其中有更多解决方案可以执行此特定的查找和替换任务。

【问题讨论】:

  • 你可以从sed 's/pow(var,2)/square(var)/g' <filename>开始;是针对所有文件还是仅针对已知包含该模式的文件运行它取决于您;是否覆盖当前文件或创建新文件取决于您
  • 感谢@markp-fuso,但事实上var 是符合上述两个事实的任何变量名的占位符。我进行了编辑以反映它是占位符的事实。
  • 一般来说:sed "s/pow${var},2)/square(${var})/g" <filename>;如果您的变量的内容包含任何会影响 sed 行为的“特殊”字符,您可能会遇到麻烦......如果是这种情况,您需要提供更多详细信息(否则您'将再次结束您的问题)
  • @markp-fuso:再次感谢。我添加了有关 var 的更多详细信息。具体来说,它仅包含[A-Z][a-z] 和/或_
  • @markp-fuso:谢谢!我已经接受了您的回答,因为它运行良好。我将尝试使用其中包含的原则使用var="(?<=pow\().*?(?=,2\))" 发布另一个答案。再次感谢您指导我完成此操作。

标签: regex bash sed replace


【解决方案1】:

条款和假设:

  • OP 提到需要处理多个文件;对于这个答案,我将专注于单个文件;如果多文件解决方案出现问题,OP 可以提出另一个问题
  • OP 提到想要replace 一些字符串,但不清楚(对我来说)是要覆盖原始文件还是要创建新文件;对于这个答案,我将专注于生成“修改后的”输出; OP 可以根据最终要求扩展此解决方案(如下)
  • 示例似乎暗示了 4 种不同的搜索模式(alphabetabetaR_redepsilon_gamma);我假设可能需要搜索的模式数量不定
  • 为简单起见,我将假设搜索模式存储在数组中
  • 搜索模式不包含前导/尾随空格
  • 搜索模式相对简单,并且包含任何特殊字符(例如,换行符)

示例输入文件:

$ cat input.txt
pow(alpha,2) + pow(beta,2)
(3*pow(betaR_red,2))
2/pow(gammaBlue,3))
-pow(epsilon_gamma,2)+5

搜索模式数组:

$ var=(alpha beta betaR_red epsilon_gamma 'double helix')
$ typeset -p var
declare -a var=([0]="alpha" [1]="beta" [2]="betaR_red" [3]="epsilon_gamma" [4]="double helix")

总体思路是使用sed根据var[]数组的内容对文件进行多模式搜索。这意味着我们需要一种方法以适合sed 多模式匹配的方式引用数组(即,值需要用管道分隔 (|)。

通过分配IFS='|',我们可以“重新格式化”数组内容以用作sed 的多模式搜索字符串:

$ echo "${var[*]}"
alpha beta betaR_red epsilon_gamma double helix
$ IFS='|' varX="${var[*]}" ; echo "${varX}"
alpha|beta|betaR_red|epsilon_gamma|double helix

这将我们带到sed 命令:

$ IFS='|' sed -E "s/pow\((${var[*]}),2\)/square(\1)/g" input.txt

地点:

  • sed -E - 在扩展的正则表达式支持下运行
  • pow\( / ,2\) - 搜索我们的 pow(..,2) 字符串,转义括号,因此它们不会被评估为正则表达式组的分隔符
  • IFS='|' / (${var[*]}) - 使用 '|' 作为值分隔符扩展数组 var;通过包裹在括号中,这将成为我们的第一个(也是唯一的)搜索组
  • square( / ) - pow( / ,2) 模式的替换字符串
  • \1 - 复制我们搜索组的内容,例如,如果我们在 pow(beta,2) 上匹配,则 \1 == beta

如果我们以set -xv ; IFS='|' sed ...; set +xv 执行上述操作,我们将生成以下“调试”输出,显示如何使用var 数组的值扩展sed 命令:

++ IFS='|'
++ sed -E 's/pow\((alpha|beta|betaR_red|epsilon_gamma|double helix),2\)/square(\1)/g' input.txt

上述sed命令的实际输出:

square(alpha) + square(beta)          # 2x changes
(3*square(betaR_red))                 # 1x change
2/pow(gammaBlue,3))                   # no changes
-square(epsilon_gamma)+5              # 1x change

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多