全局搜索+替换,但仅限于测试通过的情况

全局搜索+替换,但仅限于测试通过的情况

我想对文件目录进行全局搜索和替换。有多种方法可以做到这一点(许多编辑器,sed+find),但我有一个额外的要求。我希望,对于每个可能的替换,运行一个 shell 脚本,并且仅在脚本通过时才保留更改。

举个例子,假设我决定在 Rust 代码中过多地使用“pub”,并且想要尝试让我的代码“不那么公开”。

我可以运行:sed -e 's/pub//g' -i $(find . -name "*.rs")来删除所有出现的pub,但其中一些是必需的,因此我想尝试pub一次删除 s 一个,cargo check在每一个之后运行。

答案1

您的描述表明您必须测试任何单个替换并保留它或回滚。因此,您可以就地进行修改、测试,并在失败时恢复备份文件,如果成功则不执行任何操作。

此外,您还必须跟踪发生的情况,以免再次测试相同的被拒绝的更改。假设该模式可能在一行中出现一次,您可以对一个文件使用类似的内容:

line_numbers=( $(sed -n '/pub/=' "$1") )

for i in "${line_numbers[@]}"; do
    sed -i.old "${i}s/pub//" "$1" && run_test || mv "$1.old" "$1"
done

我们只存储出现的行号,以便我们对每个案例测试一次。第一个sed类似于grep -n仅获取行号。如果没有匹配项,则以下循环将运行零次。第二种sed是仅替换特定的行号$i。双引号用于将变量扩展为 sed 表达式。

并为您的文件运行它:

find . -type f -name '*.rs' -exec sh script.sh {} \;

此外,您还必须清理所有*.old备份文件,并选择目标目录中不存在的备份扩展名。

请注意,根据您的文件结构、模式的频率以及run_test您实际运行的情况,这可能会很慢,因为我们调用了许多进程。另外,在运行任何操作之前,请务必确保对数据进行了良好的备份。

相关内容