Maneira inteligente de executar uma substituição semelhante (não simples o suficiente para diff) em vários arquivos?

4

Eu tenho um monte de arquivos (45, muitos para editá-los manualmente sem enlouquecer), que requerem as mesmas alterações (como visto nos três diffs no final desta questão).

A maioria das ferramentas usadas para pesquisa e substituição na linha de comando suporta apenas substituições linha a linha, para que não funcionem.

Existe alguma ferramenta de linha de comando disponível que pode fazer o trabalho? Basicamente, executar uma pesquisa de regex de várias linhas e substituí-la por referências anteriores sem colocar todo o regex em uma única linha (por exemplo, deve ser lido em um arquivo ou stdin) deve ser suficiente, mas talvez haja uma solução ainda melhor para fazer isso ...

--- 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>

Se o recuo não for preservado, não é um grande problema.

    
por ThiefMaster 13.09.2012 / 23:50

3 respostas

1

Vamos simplificar. Os arquivos se encaixam confortavelmente na memória, então não se incomode em lê-los linha por linha ou qualquer coisa assim. O -p do Perl (iterar sobre o conteúdo do arquivo) e -0777 “modo slurp” (leia um arquivo inteiro de uma vez, não linha por linha) são convenientes.

Para atuar em vários arquivos, é conveniente usar -i (editar arquivos no lugar).

Para realizar a substituição, use o operador de substituição s . Veja perlre # Modifiers para uma explicação dos modificadores 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 corresponde a todos os arquivos .js no diretório atual e seus subdiretórios recursivamente. Isso funciona fora da caixa em zsh. Se você usar o bash, adicione shopt -s globstar ao seu ~/.bashrc .

(não testado, você provavelmente terá que ajustar um pouco o regexp).

    
por 14.09.2012 / 04:00
1

Despeja a saída para stdout, por isso não vai colocar seus arquivos no lixo.

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

Testado para todos os três exemplos. A indentação não está correta para as linhas de substituição, embora o código esteja correto, e a primeira linha da substituição será iniciada no lugar certo.

$ 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>
    
por 14.09.2012 / 05:02
1

Tudo o que você pode fazer com: o modo ex no vi pode ser transformado em um script para ed

ed é como vi , mas sem toda essa interface amigável e irritante que atrapalha e atrapalha você.

Brincadeiras à parte, ed é uma ferramenta útil para a edição de arquivos de texto com scripts.

    
por 14.09.2012 / 07:49