2016-05-17 15 views
0

Ich versuche, eine Datei für IP-Adressen zu analysieren und sie dann durch eine 1 für 1 zugeordnete IP-Adresse zu ersetzen. Suchen Sie beispielsweise alle Instanzen von 1.1.1.1 und ersetzen Sie diese durch 100.100.1.1 und alle Instanzen von 5.5.5.5 und ersetzen Sie diese durch 100.100.5.5. Es kann Tausende von IPs geben, daher möchte ich die Datei nicht für jede Substitution mit statischen sed Befehlen analysieren.Ersetzen Sie eine Zeichenfolge in Bash mit einer Variablen basierend auf dieser Zeichenfolge

Ich versuche, eine assoziative Array dafür zu verwenden, aber ich bin kurz.

echo "1.1.1.1 5.5.5.5" > testfile.txt 
declare -A testarray 
testarray[ip_1.1.1.1]="100.100.1.1" 
testarray[ip_5.5.5.5]="100.100.5.5" 
sed -r "s/(([0-9]{1,3}\.){3}[0-9]{1,3})/${testarray[ip_\1]}/g" testfile.txt 

Die Verwendung der Erfassungsgruppe innerhalb der Variablen funktioniert nicht. Die direkte Verwendung des Textes funktioniert jedoch.

sed -r "s/(([0-9]{1,3}\.){3}[0-9]{1,3})/${testarray[ip_1.1.1.1]}/g" testfile.txt 
100.100.1.1 100.100.1.1 

Natürlich ist diese alle IPs mit 100.100.1.1 ersetzt, möchte ich auf der Grundlage der Array Vereinigung ersetzen.

Gibt es eine Möglichkeit, eine Erfassungsgruppe zu verwenden und sie in einer Variablen für einen Ersatz in Bash zu verwenden? Ich habe ein paar Varianten versucht, mit Anführungszeichen sowie ein Variable im Voraus erstellen, die auf ‚\ 1‘ hängt immer noch, aber es entweder nicht oder nur gibt die wörtliche Ausgabe des Variable. Ich weiß nicht, ob es ein besseres Werkzeug als sed dafür gibt. Ich habe auch versucht, Variablen anstelle eines Arrays zu verwenden, aber ich stieß auf das gleiche Problem.

+0

Sie rufen den Index dynamisch mit 'ip_ \ 1' auf. Das heißt, die erfasste Gruppe verwenden. Dies ist nicht möglich, wie Sie es jetzt tun, aber wahrscheinlich müssen Sie 'sed'' e' Flag verwenden, um Sachen auszuführen. Sehen Sie zum Beispiel [diese Antwort von anubhava] (http://stackoverflow.com/a/34080390/1983854) für ein schönes Beispiel. – fedorqui

+2

Perl unterstützt sowohl Substitutions- als auch assoziative Arrays (Hashes). Ich würde es anstelle von sed verwenden. – choroba

+0

Danke für den Link @jil, ich habe es noch nicht geschafft, die verknüpfte Awk-Lösung zu verwenden, aber ich habe keine Erfahrung mit Awk, daher kann ich nicht leicht sagen, ob das das Problem löst. Nach meiner Lektüre mag es das nicht. – suretass

Antwort

0

POSIX-Shell-Skript, eingegeben testfile.txt, Komma getrennt "von zu" -Paare in replacements.txt sind:

echo 1.1.1.1 100.100.1.1 ,5.5.5.5 100.100.5.5 | tr ',' '\n' > replacements.txt 
echo "1.1.1.1 6.7.8.9 5.5.5.5" | tr ' ' '\n' > testfile.txt 

while read x ; do 
    while read a b ; do 
     if [ $a = $x ] ; then 
      x=$b 
      break 
     fi 
    done < replacements.txt 
    echo $x 
done < testfile.txt 

Output:

100.100.1.1 
6.7.8.9 
100.100.5.5 

Anmerkungen: ineffizienten , es liest mindestens eine Zeile von replacements.txt für jede Zeile von testfile.txt, aber das erlaubt Ersatzlisten größer als bash 's verfügbaren Speicher.