我有一堆文件(45 个,太多了,无法手动编辑它们而不会发疯),它们都需要相同的更改(如本问题末尾的三个差异所示)。
大多数用于在命令行上进行搜索和替换的工具仅支持逐行替换,因此它们不起作用。
是否有一些可用的命令行工具可以完成这项工作?基本上执行多行正则表达式搜索和反向引用替换,而不将整个正则表达式推入一行(即应该从文件或标准输入中读取)应该足够了,但也许有更好的解决方案来做到这一点......
--- a/editfile.html
+++ b/editfile.html
@@ -60,7 +60,5 @@
<script type="text/javascript">
- $(document).ready(function() {
- editFileInit(opts);
- });
+ initPage('editFile', opts);
</script>
{% endblock %}
diff --git a/gallery.html b/gallery.html
index 4a07f70..81084ad 100644
--- a/exodus/templates/gallery.html
+++ b/exodus/templates/gallery.html
@@ -87,9 +87,7 @@
<script type="text/javascript">
- $(document).ready(function() {
- galleryInit({
- editTitleUrl: {{ csrf_url_for('gallery_editpictitle')|tojson|safe }},
- delPicUrl: {{ csrf_url_for('gallery_delpic')|tojson|safe }}
- });
+ initPage('gallery', {
+ editTitleUrl: {{ csrf_url_for('gallery_editpictitle')|tojson|safe }},
+ delPicUrl: {{ csrf_url_for('gallery_delpic')|tojson|safe }}
});
</script>
diff --git a/stream_history.html b/stream_history.html
index 783fea4..ea837fa 100644
--- a/exodus/templates/stream_history.html
+++ b/exodus/templates/stream_history.html
@@ -25,8 +25,6 @@
<script type="text/javascript">
- $(document).ready(function() {
- songHistoryInit({
- dataURL: {{ url_for('stream_history_json')|tojson|safe }}
- });
+ initPage('songHistory', {
+ dataURL: {{ url_for('stream_history_json')|tojson|safe }}
});
</script>
如果不保留缩进,那么这不是一个大问题。
答案1
答案2
让我们保持简单。这些文件适合内存中,因此不必费心逐行读取它们或类似的内容。珀尔的-p
(迭代文件内容)开关和-0777
“吸食模式”(一次读取整个文件,而不是逐行读取)很方便。
作用于多个文件,使用起来很方便-i
(就地编辑文件)。
要执行替换,请使用s
替换运算符。看perlre#修饰符有关修饰符的解释msx
。
perl -0777 -i.orig -p -e '
s[
^(\s+) # indentation
\Q$(document).ready(function() {\E\n
\s*(\w+)Init # function name
(\(((?:(?>[^()]+)|(?3))*)\)) # balanced parentheses
;\n\s*\}\);
][
${1}initPage(\x27$2\x27, $3);
]msx;
' **/*.js
**/*.js
.js
递归匹配当前目录及其子目录中的所有文件。这在 zsh 中是开箱即用的。如果您使用 bash,请将其添加shopt -s globstar
到您的~/.bashrc
.
(未经测试,您可能需要稍微调整正则表达式。)
答案3
将输出转储到标准输出,因此不会将文件丢弃。
#!/usr/bin/perl
use strict;
use warnings;
# Slurp our input...
my $text = do {local $/; <> };
# Extract the varying parts: foo and bar, for fooInit(bar)
my ($init_prefix, $init_opts) = $text =~ m/([a-zA-Z0-9]+)Init\(([^;]+;)/m;
# Construct the replacement: fooInit(bar) -> initPage('foo', bar)
my $replace_with = "initPage('$init_prefix', $init_opts";
# Target the text to replace...
my $to_replace = '\$\(document.*;';
# Perform the replacement;
$text =~ s/$to_replace/$replace_with/gs;
print $text;
对您的所有三个示例进行了测试。尽管代码是正确的,并且替换的第一行将在正确的位置开始,但替换行的缩进不正确。
$ perl replace.pl 1.js
script type="text/javascript">
initPage('editFile', opts);
</script>
{% endblock %}
$ perl replace.pl 2.js
<script type="text/javascript">
initPage('gallery', {
editTitleUrl: {{ csrf_url_for('gallery_editpictitle')|tojson|safe }},
delPicUrl: {{ csrf_url_for('gallery_delpic')|tojson|safe }}
});
</script>
$ perl replace.pl 3.js
<script type="text/javascript">
initPage('songHistory', {
dataURL: {{ url_for('stream_history_json')|tojson|safe }}
});
</script>