Wie kann ich mit SED oder AWK Platzhalter in einer Vorlagendatei durch variablen Inhalt ersetzen, der Sonderzeichen enthält?

8

CentOS 6.3

Ich versuche, ein kleines Skript zum Senden einer E-Mail mit einer Kopie der E-Mail-Header im Textkörper zu erstellen (zum Zwecke der internen Berichterstellung).

Die Vorlagendatei enthält Folgendes:

Alert Report

Alert has triggered at TMPDATE

HEADERS
-------
TMPHEADERS

SOURCE IP
---------
TMPSOURCEIP

Ich möchte, dass mein Skript die Platzhalter "TMP" findet und durch tatsächliche Informationen ersetzt, die für die Warnung relevant sind.

Die Datums- und Quell-IP-Variablen scheinen gut zu funktionieren, aber wenn ich versuche, die TMPHEADERS zu finden / zu ersetzen, entstehen seltsame Symptome, einschließlich der Tatsache, dass die gesamte Ausgabe leer ist. Ich bin mir ziemlich sicher, dass es mit den Überschriften zu tun hat, die viele Sonderzeichen enthalten (@% & etc).

Kann jemand bitte beraten, wie dies am besten per Bash erreicht werden kann?

Mein aktueller Code sieht folgendermaßen aus:

cat /test/emailtemplate | sed s/TMPHEADERS/"$HEADERS"/ > /test/output

AKTUALISIEREN

Auf Anfrage ist hier ein Beispielsatz von Headern, die ich in die Vorlagendatei einfügen möchte (IP-Adressen und E-Mail-Adresse wurden geändert, um die Unschuldigen zu schützen :-)):

From [email protected] Thu Apr 25 20:18:19 2013
Return-Path: <[email protected]>
Received: from nm30-vm0.bullet.mail.ne1.yahoo.com (nm30-vm0.bullet.mail.ne1.yahoo.com [98.138.11.36])
by serv.example.com (8.14.4/8.14.4) with ESMTP id r3Q3IJVV009411
for <[email protected]>; Thu, 25 Apr 2013 20:18:19 -0700
Received: from [108.108.108.108] by nm30.bullet.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:19 -0000
Received: from [98.138.87.11] by tm15.bullet.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:17 -0000
Received: from [127.0.0.1] by omp1001.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:17 -0000
X-Yahoo-Newman-Property: ymail-3
X-Yahoo-Newman-Id: [email protected]
Received: (qmail 29701 invoked by uid 65501); 26 Apr 2013 03:18:17 -0000
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1366946297; bh=yjMzVONHAyJxQob7tLNdIN2RpfGHWVw1Kb5Qr+enYF8=; h=X-YMail-OSG:Received:X-Rocket-MIMEInfo:X-Mailer:Message-ID:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type; b=CQGilBx8NertE4j75dsfsdfs+IKRzIx5vlH5YdzqFLd4ThfEyMs11sdfsdfsdXsAH1yteACnwSER+QXJQ80BfLGbJnIWm+29I8A4geOPIHGKoOUCnPaD+/0bHfAps0JIcwEju8Tcvg4VDVWw=
DomainKey-Signature:a=rsa-sha1; q=dns; c=nofws;
s=s1024; d=yahoo.com;
h=X-YMail-OSG:Received:X-Rocket-MIMEInfo:X-Mailer:Message-ID:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type;
b=5TIRL55VM2J2lPLsX9iCE4sdlkfjlEM2245M6qzg1oGrnZd61ykL4xQSsc3cYNz95fwNy67aRRC89n6xcti28ee5rjmlK0MDIskSB5sKlv165mNjmzF1LNx6uFXalI8QGSwiQt2uWLYvI7RrTVeZFELDfFVZyqygEl5k=;
X-YMail-OSG: EDT4ym4VM1lVQMdtAQ5zqfE59jR1Mtip4vVL1fBzNxFdGvA
YjAJ3MXC1EusloknrsPx3drxzR1b4PFErK.UhdgWePhK7TTCHhhju4XP4i7x
76WASceqp77T5itvZmilv5UuICJw3BCEd0fdADctfBYhLNwoALxjp6cnJMmE
Z4dYVtlp5vUFqg1pHxqGOXqrtjeZffM4dMftnn.Q8LlVEkj3pZ6ZJV_kKFtj
vGEGS5PAW0tIHWPEqVERYzmDOfF5sVSQLayPi6EM_i1OE038434laijEWbH0
nZt1Vkg3syO0t1BaTLN4B1bXeS8cv3GlbLO4ot7zVwA3sH4UhsC5M6xiWNFU
3iroObJ5BObL99VO3ktvC4KzekAWJ_fE85TQJhQKj6Iolgb4xlWa2x414xuA
awO4pJI9grDjycUcmhmKwLZEt_.0OBLfSi5MSviaiCNMuU5qIdHm7VCGdORP
Mc68rDkpmJE9I9Z.QZfhH5cFxqqmpyIOMTs0iIBGYz5d9QHMWCuo-
Received: from [102.102.102.102] by web12341105.mail.ne1.yahoo.com via HTTP; Thu, 25 Apr 2013 20:18:17 PDT
X-Rocket-MIMEInfo: 002.001,VGVzdGluZyAxMjMgTGEgbGEgbGEBMAEBAQE-
X-Mailer: YahooMailWebService/0.8.141.536
Message-ID: <[email protected]>
Date: Thu, 25 Apr 2013 20:18:17 -0700 (PDT)
From: Test Account <[email protected]>
Reply-To: Test Account <[email protected]>
Subject: Test
To: "[email protected]" <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="102743210-1541163991-1366946297=:49149"
Mike B.
quelle
2
Einfache Textbearbeitungswerkzeuge haben Einschränkungen. Sie eignen sich nur für die grundlegende Handhabung von Vorlagen. Siehe Tool zum Erstellen von Textdateien aus einer Vorlage . Hat Links zu ähnlichen Fragen zu Stack Exchange und Serverfehlern , siehe auch diese.
Manatwork
Können Sie uns einige Beispiele für die fehlgeschlagenen Header geben?
Terdon
@terdon Auf jeden Fall. Ich habe die Frage aktualisiert, um einige Beispielheader (mit unterschiedlichen IP- und E-Mail-Adressen) aufzunehmen.
Mike B

Antworten:

7

Das ist schwierig in sed weil sed s/TMPHEADERS/"$HEADERS"/der Wert der Variablen durch die Schale ersetzt wird , bevor der Befehl erreicht sed, so Zeichen wie &\/die in erscheint $HEADERSeine besondere Bedeutung im Ersetzungstext hat. Sed verfügt nicht über eine variable Suchfunktion.

Diese Aufgabe ist mit awk ziemlich einfach. Übergeben Sie die HEADERSVariable in der Umgebung:

export HEADERS
</test/emailtemplate awk '
    {gsub(/^TMPHEADERS$/, environ["HEADERS"]); print}
' > /test/output

oder als awk-Variable:

</test/emailtemplate awk -v HEADERS="$HEADERS" '
    {gsub(/^TMPHEADERS$/, HEADERS); print}
' > /test/output
Gilles 'SO - hör auf böse zu sein'
quelle
3

Es gibt mehrere Möglichkeiten:

sed Sie müssten jedem Zeichen in "$ HEADERS" entkommen, um den sed-Anruf sicher zu machen.

HEADERS_ESCAPED="$(echo "$HEADERS" | sed -n 's/./\\&/gp')"
# double-useless use of cat BTW
sed "s/TMPHEADERS/$HEADERS_ESCAPED/" /test/emailtemplate > /test/output

Übrigens: Es gibt absolut keinen Grund, sed bei jeder Änderung einmal anzurufen:

sed -n -e s/X/"$X"/ -e s/Y/"$Y" -e s/Z/"$Z"/ -e p inputfile > outputfile

Bash selbst

while IFS= read -r line; do
  line="${line/TMPDATE/"$TMPDATE"}"
  # ...
  line="${line/TMPHEADERS/"$HEADERS"}"
  printf '%s\n' "$line"
done <inputfile >outputfile
Hauke ​​Laging
quelle
@terdon In der Tat war das die falsche Variable. sed erweitert nichts (aufgrund des Entweichens jedes Zeichens in der Variablen). Was meinst du? Hast du das versucht, funktioniert es nicht?
Hauke ​​Laging
Mein schlechtes, ich zitiere immer meine sedBefehle (ich dachte, das wäre notwendig) und Bash-Variablen werden nicht erweitert (ich meine, dass 's / foo / $ bar /' tatsächlich gedruckt wird $barund nicht der Inhalt der Variablen). Ihr Befehl funktionierte ohne die Anführungszeichen (wie Sie ihn veröffentlicht hatten) einwandfrei. Er schlug fehl, als ich ihn in einfache Anführungszeichen setzte. Entschuldigung, Kraft der Gewohnheit, fühlen Sie sich frei, meine Bearbeitung zurückzusetzen.
Terdon
Vielen Dank für die schnelle Hilfe, aber ich sed: -e expression #1, char 121: unterminated erhalte eine Fehlermeldung: s 'Befehl` Ich schätze, ich muss den Befehl falsch konfiguriert haben: sed "s/TMPHEADERS/$HEADERS_ESCAPED/" /home/foo/scripts/fooalert/emailtemplate > /home/foo/scripts/fooalert/testing1234 Ich habe bestätigt, dass die Header jetzt alle ordnungsgemäß maskiert sind.
Mike B
@MikeB Kannst du herausfinden, welches Zeichen das Problem verursacht? Ich bin nicht sicher, ob es möglich ist, eine neue Zeile im Ersatztext zu haben. Ist es möglich, dass $ HEADERS_ESCAPED eine neue Zeile enthält?
Hauke ​​Laging
1

Ich bin mir nicht sicher, ob ich verstehe, was Sie tun möchten. Wenn Sie beispielsweise die Zeichenfolge TMPHEADERSdurch die lange Liste der von Ihnen geposteten Header-Informationen ersetzen möchten , kann diese Perl-Lösung Folgendes tun:

perl -e 'open(A,"header"); ## open the header file
         $h=join("",<A>); ## save its contents in a string
         while(<>){ ## go through the input file
            s/TMPHEADERS/$h/; ## replace
            print        ## print each line
         }' template 

Die Datei templateist die Vorlage aus Ihrer Frage und die Datei headerenthält die von Ihnen geposteten Kopfzeilen. Das Ergebnis ist

Alert Report

Alert has triggered at TMPDATE

HEADERS
-------
From [email protected] Thu Apr 25 20:18:19 2013
Return-Path: <[email protected]>
Received: from nm30-vm0.bullet.mail.ne1.yahoo.com (nm30-vm0.bullet.mail.ne1.yahoo.com [98.138.11.36])
by serv.example.com (8.14.4/8.14.4) with ESMTP id r3Q3IJVV009411
for <[email protected]>; Thu, 25 Apr 2013 20:18:19 -0700
Received: from [108.108.108.108] by nm30.bullet.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:19 -0000
Received: from [98.138.87.11] by tm15.bullet.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:17 -0000
Received: from [127.0.0.1] by omp1001.mail.ne1.yahoo.com with NNFMP; 26 Apr 2013 03:18:17 -0000
X-Yahoo-Newman-Property: ymail-3
X-Yahoo-Newman-Id: [email protected]
Received: (qmail 29701 invoked by uid 65501); 26 Apr 2013 03:18:17 -0000
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com; s=s1024; t=1366946297; bh=yjMzVONHAyJxQob7tLNdIN2RpfGHWVw1Kb5Qr+enYF8=; h=X-YMail-OSG:Received:X-Rocket-MIMEInfo:X-Mailer:Message-ID:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type; b=CQGilBx8NertE4j75dsfsdfs+IKRzIx5vlH5YdzqFLd4ThfEyMs11sdfsdfsdXsAH1yteACnwSER+QXJQ80BfLGbJnIWm+29I8A4geOPIHGKoOUCnPaD+/0bHfAps0JIcwEju8Tcvg4VDVWw=
DomainKey-Signature:a=rsa-sha1; q=dns; c=nofws;
s=s1024; d=yahoo.com;
h=X-YMail-OSG:Received:X-Rocket-MIMEInfo:X-Mailer:Message-ID:Date:From:Reply-To:Subject:To:MIME-Version:Content-Type;
b=5TIRL55VM2J2lPLsX9iCE4sdlkfjlEM2245M6qzg1oGrnZd61ykL4xQSsc3cYNz95fwNy67aRRC89n6xcti28ee5rjmlK0MDIskSB5sKlv165mNjmzF1LNx6uFXalI8QGSwiQt2uWLYvI7RrTVeZFELDfFVZyqygEl5k=;
X-YMail-OSG: EDT4ym4VM1lVQMdtAQ5zqfE59jR1Mtip4vVL1fBzNxFdGvA
YjAJ3MXC1EusloknrsPx3drxzR1b4PFErK.UhdgWePhK7TTCHhhju4XP4i7x
76WASceqp77T5itvZmilv5UuICJw3BCEd0fdADctfBYhLNwoALxjp6cnJMmE
Z4dYVtlp5vUFqg1pHxqGOXqrtjeZffM4dMftnn.Q8LlVEkj3pZ6ZJV_kKFtj
vGEGS5PAW0tIHWPEqVERYzmDOfF5sVSQLayPi6EM_i1OE038434laijEWbH0
nZt1Vkg3syO0t1BaTLN4B1bXeS8cv3GlbLO4ot7zVwA3sH4UhsC5M6xiWNFU
3iroObJ5BObL99VO3ktvC4KzekAWJ_fE85TQJhQKj6Iolgb4xlWa2x414xuA
awO4pJI9grDjycUcmhmKwLZEt_.0OBLfSi5MSviaiCNMuU5qIdHm7VCGdORP
Mc68rDkpmJE9I9Z.QZfhH5cFxqqmpyIOMTs0iIBGYz5d9QHMWCuo-
Received: from [102.102.102.102] by web12341105.mail.ne1.yahoo.com via HTTP; Thu, 25 Apr 2013 20:18:17 PDT
X-Rocket-MIMEInfo: 002.001,VGVzdGluZyAxMjMgTGEgbGEgbGEBMAEBAQE-
X-Mailer: YahooMailWebService/0.8.141.536
Message-ID: <[email protected]>
Date: Thu, 25 Apr 2013 20:18:17 -0700 (PDT)
From: Test Account <[email protected]>
Reply-To: Test Account <[email protected]>
Subject: Test
To: "[email protected]" <[email protected]>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="102743210-1541163991-1366946297=:49149"


SOURCE IP
---------
TMPSOURCEIP

Sie können dies für zwei Sätze von Headern wie folgt erweitern:

perl -e 'open(A,"header1");
         $h1=join("",<A>);
         open(B,"header2");
         $h2=join("",<B>);
         while(<>){
            s/TMPHEADERS/$h1/;
            s/TMPSOURCEIP/$h2/;
            print        
         }' template 
terdon
quelle
Ich respektiere diese Antwort, aber leider kenne ich Perl nicht gut genug, um sie fortlaufend aufrechtzuerhalten. Mir ist klar, dass dies keine gute Antwort ist (oder ein Grund, keinen effizienteren Code zu verwenden). Vielen Dank.
Mike B
1

Verwenden des m4Makroprozessors zum Ersetzen TMPSOURCEIPund TMPDATEdurch Dinge, die in der Befehlszeile definiert sind, und TMPHEADERSdurch alles, was in der Datei enthalten ist headers.txt. Die Vorlage ist in template.txt.

$ m4 -DTMPDATE="$(date)" -DTMPSOURCEIP="1.1.1.1" -DTMPHEADERS='include(headers.txt)' template.txt
Alert Report

Alert has triggered at Mon Sep 25 18:46:34 CEST 2017

HEADERS
-------
From foo@yahoo.com Thu Apr 25 20:18:19 2013
Return-Path: <foo@yahoo.com>
Received: from nm30-vm0.bullet.mail.ne1.yahoo.com (nm30-vm0.bullet.mail.ne1.yahoo.com [98.138.11.36])
by serv.example.com (8.14.4/8.14.4) with ESMTP id r3Q3IJVV009411
(etc.)


SOURCE IP
---------
1.1.1.1

Wenn Sie bereits die Überschriften in einer Variablen haben, können Sie natürlich ersetzen -DTMPHEADERS='include(headers.txt)'mit -DTMPHEADERS="$headers".

Kusalananda
quelle