2014-04-12 2 views
1

내가 다음 스크립트를 썼다 출력에 추가 문자 (작은 따옴표)를 제공합니다펄 정규식 대체 나에게

#!/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> 

이상한 것이 있습니다 : 왜 여분의 문자가 있습니까? 르 인용구) 스크립트 끝 태그 후? 어떤 도움 주셔서 감사합니다

답변

1

내가 의도 한대로 작동하도록 변경 유일한 라인은 없다 : 그것을 고정 이유

result_string="${codice//$string_to_search/$string_to_replace}" # it escapes also slashes "/" 

나도 몰라, 어느 쪽도 아니 당신은 /하려는 이유에 대한 printf %q "$codice"이 필요하여 uses

1

셸 스크립트 내에 '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}을 셸 변수로 포함합니다. 그리고 작은 따옴표와 큰 따옴표를 조합하여 인용합니다.

필자는 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>,$codice\n</body></html>,gi; 
    print {$output_fh} $input_text; 
    close $output_fh; 
    } 
} 

find (\&insert_codice, "."); 

나는 당신이 원하는대로 할 것이라고 생각합니다. 당신은 파일에 대한 자세한 내용을 찾을 수 있습니다 :: 찾기 모듈 - 기본적으로 perldoc을 재귀 디렉토리 탐색을하는 깔끔한 방법입니다 http://perldoc.perl.org/File/Find.html

+0

저는 Perl의 초보자입니다. 어쩌면 첫 번째 줄은 #!/usr/bin/perl (첫 번째 슬래시를 놓쳤을 것임) 일 것입니다. 그러나 코드가 내 컴퓨터에서 실행되지 않습니다.이 오류가 있습니다. /usr/share에 서브 루틴을 지정하지 않았습니다. /perl/5.14/File/Find.pm 라인 1064 –

+0

파일에 대한 세부 정보 : 여기에 있어야합니다 : http://perldoc.perl.org/File/Find.(I 그에 따라 수정하여야한다)', 이'(".", \ & insert_codie를) 찾을 :; 그래서' 는'발견 (\ & 원, @directories_to_search) : - 내 부분에 HTML 오타 다른 ​​방법으로 주위해야한다 – Sobrique

+0

좋은 조언을 위해 @Sobrique +1. Btw,'next' 대신'return'을 원합니다. 나는 또한 코드를 강화하려고했지만 새로운 게시물을 만드는 것이 더 적절하다고 느껴지는 많은 변화를 가져 왔습니다. – Miller

0

Sobrique 이미 권고 한 바와 같이,이 사용하여 순수한 펄을하는 것은 여러분의 인생을 더 쉽게 만들 수 있습니다 . 다음 스크립트는 또한 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 파일에 이미 포함되어 있다고 생각되는 경우 Google 애널리틱스를 추가하지 않는 일부 기능이 향상되었습니다. 또한 백업을 삭제하려는 경우 unlink이 포함 된 줄의 주석 처리를 제거 할 수 있습니다.