在重写遗留应用程序时,我通过foo
进行了大量替换bar
并混合了许多手动更改。一些替换必须手动撤消,原始代码中已经有许多其他bar
。
现在,我发现由foo
取代的每个bar
实际上应该是baz
。
一个例子:
a staying "foo" and a replaced "foo" and a kept "bar"
a staying "foo" and a replaced "bar" and a kept "bar"
a staying "foo" and a replaced "baz" and a kept "bar"
想要的操作很简单:将foo
的{{1}}的每次替换修复为bar
。我想知道使用baz
或任何Linux工具是否有一种简单的方法。
也许这句单句更清晰:
鉴于文件的两个版本,请将git
放在旧版本包含baz
且新版本包含foo
的每个位置。
实际上有三个整个单词替换为不同长度的单词
bar
答案 0 :(得分:3)
您可以使用git diff
的{{3}}模式(以及传递给-U
选项的足够大的值,以便保留更改之间的所有上下文)和流程它的输出带有足够简单的脚本,可以纠正错误的替换。
--word-diff[=<mode>]
显示单词diff,使用<mode>
分隔更改的单词。默认情况下,单词由空格分隔; 请参阅下面的--word-diff-regex
。<mode>
默认为plain
,和 必须是以下之一:
- ...
porcelain
:使用专门用于脚本消费的基于行的特殊格式。通常会打印添加/删除/未更改的运行 统一的diff格式,以+ / - /``字符开头 该行的开头并延伸到该行的末尾。换行 输入中的波浪号~
表示在它自己的行上。
您将在下面找到基于sed
原型的上述方法的实现。
<强>用法强>:
fix_wrong_replacements
path
revision
replacement_fix
,其中
path
是工作树中文件的(相对)路径revision
是修订版本,因此必须修复错误的替换 replacement_fix
是
/orig_pattern/incorrect_replacement_str/correct_replacement_str/
<强>效果强>:
假设比较时 path
的文件的工作副本
其提交的修订版 revision
包含替换结果
带有 orig_pattern
的 incorrect_replacement_str
的某些实例,
识别这些替换并将其更改为 correct_replacement_str
。
<强>实施例强>:
# In last two commits (and, maybe, in the working copy) some "int"s
# were incorrectly changed to "unsigned", now change those to "long"
$myname main.c HEAD~2 /int/unsigned/long/
# In the working copy of somefile.txt all "abc" case-insensitive words
# were changed to "pqrs", now change them to "xyz"
$myname somefile.txt HEAD '/[aA][bB][cC]/pqrs/xyz/'
已知限制/问题:
适用于单个文件。要修复提交,提交范围或本地更改中的所有错误替换,必须标识已更改文件的列表,并在所有这些文件的循环中调用此脚本。
如果在原始(错误)更换期间使用了不区分大小写的模式,那么 orig_pattern
参数的replacement_fix
部分必须使用{{ 1}},[aA]
等,每个字母的正则表达式原子。
不会处理与其他更改紧邻的替换。
有时可能会添加多余的空白行(因为[bB]
的输出略有不一致)
<强> fix_wrong_replacements 强>:
git diff --word-diff
答案 1 :(得分:-2)
替换foo:grep -rl&#39; foo&#39; 。 | xargs sed -i&#39; s / foo / bar / g&#39;
替换bar:grep -rl&#39; bar&#39; 。 | xargs sed -i&#39; s / bar / baz / g&#39;