Zamiana wierszy tekstu na inny w różnych plikach w Uniksie

2

Mam listę ponad 200 plików rozszerzeń powiązań z dokładnymi informacjami o subdomenach.

Przykładowy schemat wygląda następująco.

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

Muszę zastąpić całą linię zestawem trzech różnych linii, podoba mi się to.

subdomain                    A       200.201.202.204
subdomain                    A       200.201.202.205
subdomain                    A       200.201.202.206

Masz pomysł, jak wykonać takie zastąpienie we wszystkich /named_ext/plikach?

Jaskółka oknówka
źródło
1
Czy więc wyszukiwanie byłoby * A 200.201.202.203- innymi słowy, jakąkolwiek nazwą subdomeny, ale konkretnym adresem A i IP, czy też subdomena jest taka sama w każdym pliku?
Paul,
subdomena jest taka sama w każdym pliku.
Martin
1
Czy wartości IP, które należy dodać, zawsze są przyrostami oryginalnego adresu IP, czy są stałe?
przemówienie
są stałymi.
Martin

Odpowiedzi:

2

Możesz użyć następującego skryptu perla, exchange_ips.plaby wymienić ip przez trzy stałe ips (funkcja exchange_const()) lub przez trzy przyrostowe ips (funkcja exchange_incr()). Po prostu dodaj komentarz ( #) przed wywołaniem funkcji na końcu skryptu, którego nie potrzebujesz.

Pamiętaj, że co najmniej jeden przyrostowy IPS będzie niepoprawny, jeśli oryginalny adres IP kończy się na 253lub wyższy.

Skrypt modyfikuje wszystkie linie zaczynające się od $domainname. Jeśli nazwa domeny nie ma znaczenia lub jeśli pliki zawierają tylko wiersze tylko dla jednej / tej samej domeny, ustaw my $domainname = ".+";.

#! / usr / bin / perl

stosować ścisłe;
używać ostrzeżeń;

my @data = <STDIN>;

moja $ nazwa_domeny = „subdomena”;
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 $ znaleziono = 0;
    foreach (@ $ dataref) {
        if ($ _ = ~ m / $ pattern /) {
            chyba że ($ znaleziono) {
                $ znaleziono = 1;
                printf "% s% s \ n% s% s \ n% s% s \ n", 1 $, $ const_ip1, $ 1, $ const_ip2, $ 1, $ const_ip3;
            }
        } else {
            wydrukuj $ _;
        }
    }
}

sub exchange_incr ($) {
    my $ dataref = shift;
    my $ znaleziono = 0;
    foreach (@ $ dataref) {
        if ($ _ = ~ m / $ pattern /) {
            chyba że ($ znaleziono) {
                $ znaleziono = 1;
                my $ const = 1 $;
                my @iparr = split /\./, 2 $;
                dla (1 .. 3) {
                    $ iparr [3] ++;
                    printf "% s% s \ n", $ const, dołącz ".", @iparr;
                }
            }
        } else {
            wydrukuj $ _;
        }
    }
}

# wymiana ip ze stałym IP
exchange_const (\ @ data);

# wymiana ip z przyrostowym IPS
exchange_incr (\ @ data);

Wywołaj skrypt w następujący sposób:

perl exchange_ips.pl < your_file

Pętla nad wszystkimi plikami (z kopią zapasową):

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

Przykład:

Przykładowy plik do modyfikacji:

# trochę foo
subdomena A 200.201.202.203
# duplikować
subdomena A 200.201.202.203
# jakiś bar
inna domena A 99,99.99.99
inna domena A 1.1.1.1
# inny duplikat
subdomena A 200.201.202.203

Wyjście exchange_const():

# trochę foo
subdomena A 123.123.123.123
subdomena A 124.124.124.124
subdomena A 125.125.125.125
# duplikować
# jakiś bar
inna domena A 99,99.99.99
inna domena A 1.1.1.1
# inny duplikat

Wyjście exchange_incr():

# trochę foo
subdomena A 200.201.202.204
subdomena A 200.201.202.205
subdomena A 200.201.202.206
# duplikować
# jakiś bar
inna domena A 99,99.99.99
inna domena A 1.1.1.1
# inny duplikat
mówca
źródło
Świetnie, ale pętla nie działa dla mnie. Wygląda na to, że nie tworzy plików Bak.
Martin
Widzę, że w niektórych przypadkach linia początkowa jest zadeklarowana dwukrotnie z tym samym adresem IP. Czy istnieje regex w celu usunięcia drugiego, aby uniknąć powielenia zwrotu i uniknąć uzyskania 6 wierszy?
Martin
@Martin Możesz spróbować zmienić rename s/$/.bak/ $f;na mv $f $f.bak;w pętli, jeśli renamenie działa. Ponadto edytowałem odpowiedź / skrypt, aby filtrować duplikaty, po prostu zapamiętując znalezioną linię i ignorując kolejne dopasowania.
przemówienie
2

Mały skrypt bashowy

Możesz to zrobić za pomocą prostego sedpolecenia nad każdym plikiem:

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

Wyjaśnienie

Pętla for wylicza ./named_ext/*i uruchamia sedlinię za pomocą pliku $f. -rPrzedłuży regularne expressian i -ibędzie edytować plik na swoim miejscu.

Wyrażenie regularne zastępuje

subdomain                    A       200.201.202.203

z dowolną liczbą spacji wg

subdomain A 200.201.202.204
subdomain A 200.201.202.205
subdomain A 200.201.202.206

Jeśli chcesz zachować odstępy, możesz dodać spacje w sedlinii.

Tamara Wijsman
źródło
1
+1 Wreszcie dobre rozwiązanie z sed! ;)
speakr
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
Theodros Zelleke
źródło