我编写了以下脚本:
#!/bin/bash
# Add Google Analytics code to every html file in the current folder and subfolders
codice="<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'example.net');
ga('send', 'pageview');
</script>"
original_string=$(printf %q "$codice") # it expands the string in a shell-escaped format
string_to_search='/'
string_to_replace='/'
result_string="${original_string//$string_to_search/$string_to_replace}" # it escapes also slashes "/"
recursive() {
for file in *; do
if [ -d "$file" ]; then
(cd "$file"; recursive)
fi
if [[ "$file" =~ .html?$ ]]; then
perl -i.bak -e 'undef $/; $_=<>; s/</body>n</html>/n'"${result_string}"'n</body>n</html>/gi; print' $file
echo $file fatto
fi
done
}
recursive
这是一个示例输入文件:
<html>
<head>
</head>
<body>
test page
</body>
</html>
脚本执行后,文件被修改为:
<html>
<head>
</head>
<body>
test page
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'example.net');
ga('send', 'pageview');
</script>'
</body>
</html>
有一件奇怪的事情:为什么在脚本结束标记后面有一个额外的字符(单引号)?感谢您的帮助
我更改的唯一一行使其按预期工作是:
result_string="${codice//$string_to_search/$string_to_replace}" # it escapes also slashes "/"
我不知道它为什么修复了它,也不知道你为什么想要/需要一个printf %q "$codice"
来使用
不想对在shell脚本中嵌入"perl-e"的固有肮脏性发表评论。您的正则表达式是:
s/</body>n</html>/n'"${result_string}"'n</body>n</html>/gi;
为了清楚起见,您可能会发现将分隔符"/"换成逗号是值得的。
s,</body>n</html>,n'"${result_string}"'n</body>n</html>,gi;
无论如何,我认为问题的核心是在正则表达式中嵌入一个'
,但也将其用作perl -e
的分隔符。因此,实际上,您将一个字符串文本传递给perl,然后将${result_string}
作为shell变量嵌入,然后再继续您的模式。然后用单引号和双引号混合引用。
相反,我强烈考虑将bash脚本重写为纯perl,因为从长远来看,这会让生活变得更好。
#!/usr/bin/perl
# Add Google Analytics code to every html file in the current folder and subfolders
use File::Find;
use warnings;
use strict;
my $codice="<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'example.net');
ga('send', 'pageview');
</script>";
sub insert_codice
{
my $filename = $File::Find::name;
return unless $filename =~ m/.html?Z/;
{
my $backup = "$filename.bak";
local $/ = undef;
open ( my $input_fh, "<", $filename );
my $input_text = <$input_fh>;
close ( $input_fh );
open ( my $backup_fh, ">", "$filename.bak" );
print {$backup_fh} $input_text;
close $backup_fh;
open ( my $output_fh, ">", $filename );
$input_text =~ s,</body>n</html>,$codicen</body></html>,gi;
print {$output_fh} $input_text;
close $output_fh;
}
}
find ( &insert_codice, "." );
我认为这样的事情会做你想做的事。您可以在File::find模块上找到更多详细信息,这基本上是在perldoc上进行递归目录遍历的一种更整洁的方法:http://perldoc.perl.org/File/Find.html
正如Sobrique已经建议的那样,使用纯perl可以让你的生活更轻松。下面的脚本也使用File::Find
,但使用了就地编辑来收紧代码。
#!/usr/bin/perl
# Add Google Analytics code to every html file in the current folder and subfolders
use warnings;
use strict;
use File::Find;
my $codice = do {local $/; <DATA>};
find(sub {
return unless /.html?Z/;
local @ARGV = $_;
local $^I = '.bak';
my $has_analytics = 0;
while (<>) {
$has_analytics ||= m{Qwww.google-analytics.com/analytics.js};
s{(?=</body>)}{$codice}i unless $has_analytics;
print;
}
#unlink "$_$^I"; # Uncomment if you want to delete the backup
}, "." );
__DATA__
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXXXXXX-X', 'example.net');
ga('send', 'pageview');
</script>
我做了一些增强,如果它认为html文件已经包含它,它将避免添加谷歌分析。此外,如果你想删除备份,你可以取消注释包含unlink
的行。