Come posso utilizzare SED o AWK per sostituire i segnaposto in un file modello con contenuto variabile che contiene caratteri speciali?


8

CentOS 6.3

Sto cercando di ottenere un piccolo script per inviare un'e-mail contenente una copia delle intestazioni e-mail nel corpo (ai fini del reporting interno).

Il file modello contiene quanto segue:

Alert Report

Alert has triggered at TMPDATE

HEADERS
-------
TMPHEADERS

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

Voglio che il mio script trovi e sostituisca i segnaposto "TMP" con le informazioni effettive pertinenti all'avviso.

Le variabili IP di data e origine sembrano funzionare bene, ma se / quando provo a trovare / sostituire TMPHEADERS, causano vuoti sintomi strani tra cui l'intero output. Sono ragionevolmente certo che abbia a che fare con le intestazioni che contengono molti caratteri speciali (@% & etc).

Qualcuno può consigliarti sul modo migliore per farlo tramite bash?

Il mio codice attuale è simile al seguente:

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

AGGIORNARE

Come da richiesta, ecco un esempio di intestazioni che sto cercando di inserire nel file modello (indirizzi IP e indirizzo e-mail sono stati modificati per proteggere gli innocenti :-)):

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
for <test@example.com>; 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: 92334348.43667.bm@omp10122422401.mail.ne1.yahoo.com
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: <136634397.44849.YahooMailNeo@web126205.mail.ne1.yahoo.com>
Date: Thu, 25 Apr 2013 20:18:17 -0700 (PDT)
From: Test Account <foo@yahoo.com>
Reply-To: Test Account <foo@yahoo.com>
Subject: Test
To: "test@example.com" <test@example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="102743210-1541163991-1366946297=:49149"

2
I semplici strumenti di manipolazione del testo hanno dei limiti, sono adatti solo per la gestione dei modelli di base. Meglio vedere Strumento per creare file di testo da un modello . Ha collegamenti a domande simili su Stack Exchange e Server Fault , vedi anche quelle.
arte

Potresti darci alcuni esempi delle intestazioni che falliscono?
terdon

@terdon Assolutamente. Ho aggiornato la domanda per includere alcune intestazioni di esempio (con ips e indirizzi email diversi).
Mike B,

Risposte:


7

Questo è difficile in sed perché in sed s/TMPHEADERS/"$HEADERS"/, il valore della variabile viene sostituito dalla shell prima che il comando raggiunga sed, quindi i caratteri come &\/quelli appaiono in $HEADERShanno un significato speciale nel testo sostitutivo. Sed non ha una funzione di ricerca variabile.

Questo compito è abbastanza semplice con awk. Passa la HEADERSvariabile nell'ambiente:

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

o come una variabile awk:

</test/emailtemplate awk -v HEADERS="$HEADERS" '
    {gsub(/^TMPHEADERS$/, HEADERS); print}
' > /test/output

3

Esistono diverse possibilità:

sed Dovresti fuggire da ogni carattere in "$ HEADERS" per rendere sicura la chiamata di sed.

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

A proposito: non c'è assolutamente alcun motivo per chiamare sed una volta per ogni modifica:

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

bash stesso

while IFS= read -r line; do
  line="${line/TMPDATE/"$TMPDATE"}"
  # ...
  line="${line/TMPHEADERS/"$HEADERS"}"
  printf '%s\n' "$line"
done <inputfile >outputfile

@terdon In effetti, quella era la variabile sbagliata. sed non espande nulla (a causa della fuga di ogni carattere nella variabile). Cosa intendi? Hai provato questo, non funziona?
Hauke ​​Laging,

Mio male, cito sempre i miei sedcomandi (ho pensato che fosse necessario) e le variabili bash non sono espanse (intendo che 's / foo / $ bar /' effettivamente stampato $bare non il contenuto della variabile). Il tuo comando ha funzionato bene senza le virgolette (come l'avevi pubblicato) non è riuscito quando l'ho messo tra virgolette singole. Spiacente, forza dell'abitudine, sentiti libero di ripristinare la mia modifica.
terdon

Grazie per l'aiuto rapido ma sto ricevendo un errore: sed: -e expression #1, char 121: unterminated s 'command` Suppongo di aver configurato il comando in modo errato: sed "s/TMPHEADERS/$HEADERS_ESCAPED/" /home/foo/scripts/fooalert/emailtemplate > /home/foo/scripts/fooalert/testing1234 ho confermato che ora le intestazioni sono state salvate correttamente.
Mike B,

@MikeB Riesci a scoprire quale carattere causa il problema? Non sono sicuro che sia possibile inserire una nuova riga nel testo di sostituzione. È possibile che $ HEADERS_ESCAPED contenga una nuova riga?
Hauke ​​Laging,

1

Non sono sicuro di capire cosa vuoi fare. Se, ad esempio, vuoi sostituire la stringa TMPHEADERScon il lungo elenco di informazioni di intestazione che hai pubblicato, questa soluzione Perl può farlo:

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 

Il file templateè il modello della tua domanda e il file headerha le righe di intestazione che hai pubblicato. Il risultato è

Alert Report

Alert has triggered at TMPDATE

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
for <test@example.com>; 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: 92334348.43667.bm@omp10122422401.mail.ne1.yahoo.com
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: <136634397.44849.YahooMailNeo@web126205.mail.ne1.yahoo.com>
Date: Thu, 25 Apr 2013 20:18:17 -0700 (PDT)
From: Test Account <foo@yahoo.com>
Reply-To: Test Account <foo@yahoo.com>
Subject: Test
To: "test@example.com" <test@example.com>
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="102743210-1541163991-1366946297=:49149"


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

Puoi estenderlo per due serie di intestazioni come segue:

perl -e 'open(A,"header1");
         $h1=join("",<A>);
         open(B,"header2");
         $h2=join("",<B>);
         while(<>){
            s/TMPHEADERS/$h1/;
            s/TMPSOURCEIP/$h2/;
            print        
         }' template 

Rispetto questa risposta, ma sfortunatamente non conosco il Perl abbastanza bene da mantenerlo su base continuativa. Mi rendo conto che non è una buona risposta (o motivo per non usare un codice più efficiente). Grazie.
Mike B,

1

Utilizzo del m4processore macro per sostituire TMPSOURCEIPe TMPDATEcon cose definite sulla riga di comando e TMPHEADERScon qualunque cosa sia presente nel file headers.txt. Il modello è 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

Se hai già le intestazioni in una variabile, puoi ovviamente sostituirle -DTMPHEADERS='include(headers.txt)'con -DTMPHEADERS="$headers".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.