Substituindo linhas de textos por outras em arquivos diferentes no Unix

2

Eu tenho uma lista de mais de 200 arquivos de extensões de vinculação com informações de subdomínio exatas.

Um exemplo de esquema é assim.

# /named_ext/db.mysite.com
subdomain                    A       200.201.202.203

Eu preciso substituir a linha inteira por um conjunto de três linhas diferentes, como esta.

subdomain                    A       200.201.202.204
subdomain                    A       200.201.202.205
subdomain                    A       200.201.202.206

Alguma ideia de como executar tal substituição em todos os arquivos /named_ext/ ?

    
por Martin 13.08.2012 / 09:01

3 respostas

2

Você pode usar o seguinte script perl exchange_ips.pl para trocar o ip por três ips constantes (função exchange_const() ) ou por três ips incrementais (função exchange_incr() ). Basta adicionar um comentário ( # ) na frente da chamada de função no final do script que você não precisa.

Observe que um ou mais ips incrementais estarão incorretos se o ip original terminar com 253 ou superior.

O script modifica todas as linhas que começam com $domainname . Se o nome do domínio não for importante ou se os arquivos contiverem apenas linhas para um único domínio, defina my $domainname = ".+"; .

#!/usr/bin/perl

use strict;
use warnings;

my @data = <STDIN>;

my $domainname = "subdomain";
my $const_ip1 = "123.123.123.123";
my $const_ip2 = "124.124.124.124";
my $const_ip3 = "125.125.125.125";

my $pattern = qr/^($domainname\s+A\s+)([\d\.]+)/is;

sub exchange_const($) {
    my $dataref = shift;
    my $found = 0;
    foreach (@$dataref) {
        if ($_ =~ m/$pattern/) {
            unless ($found) {
                $found = 1;
                printf "%s%s\n%s%s\n%s%s\n", $1, $const_ip1, $1, $const_ip2, $1, $const_ip3;
            }
        } else {
            print $_;
        }
    }
}

sub exchange_incr($) {
    my $dataref = shift;
    my $found = 0;
    foreach (@$dataref) {
        if ($_ =~ m/$pattern/) {
            unless ($found) {
                $found = 1;
                my $const = $1;
                my @iparr = split /\./, $2;
                for (1 .. 3) {
                    $iparr[3]++;
                    printf "%s%s\n", $const, join ".", @iparr;
                }
            }
        } else {
            print $_;
        }
    }
}

# exchange ip with constant ips
exchange_const(\@data);

# exchange ip with incremental ips
exchange_incr(\@data);

Chame o script assim:

perl exchange_ips.pl < your_file

Repasse todos os arquivos (com backup):

for f in /named_ext/*; do rename s/$/.bak/ $f; perl exchange_ips.pl < $f.bak > $f; done

Exemplo:

Arquivo de amostra para modificação:

# some foo
subdomain                       A       200.201.202.203
# duplicate
subdomain                       A       200.201.202.203
# some bar
otherdomain                     A       99.99.99.99
otherdomain                     A       1.1.1.1
# another duplicate
subdomain                       A       200.201.202.203

Saída de exchange_const() :

# some foo
subdomain                       A       123.123.123.123
subdomain                       A       124.124.124.124
subdomain                       A       125.125.125.125
# duplicate
# some bar
otherdomain                     A       99.99.99.99
otherdomain                     A       1.1.1.1
# another duplicate

Saída de exchange_incr() :

# some foo
subdomain                       A       200.201.202.204
subdomain                       A       200.201.202.205
subdomain                       A       200.201.202.206
# duplicate
# some bar
otherdomain                     A       99.99.99.99
otherdomain                     A       1.1.1.1
# another duplicate
    
por 13.08.2012 / 10:23
2

Pequeno script bash

Você pode fazer isso com um simples comando sed sobre cada arquivo:

for f in ./named_ext/* ; do
    sed -r -i 's/subdomain[ ]+A[ ]+200.201.202.203/subdomain A 200.201.202.204\nsubdomain A 200.201.202.205\nsubdomain A 200.201.202.206/g' $f
done

Explicação

O loop for enumera ./named_ext/* e executa a linha sed usando o arquivo $f . O -r estenderá o expressian regular e o -i editará o arquivo no lugar.

A expressão regular substitui

subdomain                    A       200.201.202.203

com qualquer número de espaços por

subdomain A 200.201.202.204
subdomain A 200.201.202.205
subdomain A 200.201.202.206

Se você quiser manter o espaçamento, adicione os espaços na linha sed .

    
por 14.08.2012 / 15:39
1
#!/bin/bash

tempFile=tempFile

for f in /named_ext/* ; do
    awk '
    BEGIN {FS = OFS = "."}

    /[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/ {
        for (i=0; i<3; i++) {
            $4++
            print $0
        }
    }' $f > $tempFile
    mv $tempFile $f
done
    
por 13.08.2012 / 10:02