Làm cách nào tôi có thể sử dụng SED hoặc AWK để thay thế chỗ dành sẵn trong tệp mẫu bằng nội dung biến có chứa các ký tự đặc biệt?


8

CentOS 6.3

Tôi đang cố gắng để có được một tập lệnh nhỏ để gửi email chứa một bản sao của các tiêu đề email trong cơ thể (cho mục đích báo cáo nội bộ).

Tệp mẫu chứa các mục sau:

Alert Report

Alert has triggered at TMPDATE

HEADERS
-------
TMPHEADERS

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

Tôi muốn tập lệnh của mình tìm và thay thế chủ sở hữu địa điểm "TMP" bằng thông tin thực tế có liên quan đến cảnh báo.

Các biến IP ngày và nguồn có vẻ hoạt động tốt nhưng nếu / khi tôi cố gắng tìm / thay thế TMPHEADERS, nó sẽ gây ra các triệu chứng lạ bao gồm toàn bộ đầu ra bị trống. Tôi khá chắc chắn rằng nó phải liên quan đến các tiêu đề có chứa nhiều ký tự đặc biệt (@% & vv).

Ai đó có thể vui lòng tư vấn về cách tốt nhất để thực hiện điều này thông qua bash?

Mã hiện tại của tôi trông như thế này:

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

CẬP NHẬT

Theo yêu cầu, đây là một tập hợp các tiêu đề tôi đang cố gắng chèn vào tệp mẫu (địa chỉ IP và địa chỉ email đã được thay đổi để bảo vệ người vô tội :-)):

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
Các công cụ xử lý văn bản đơn giản có những hạn chế, chúng chỉ phù hợp để xử lý mẫu cơ bản. Xem tốt hơn Công cụ để tạo tệp văn bản từ một mẫu . Có liên kết đến các câu hỏi Stack ExchangeServer Fault tương tự , hãy xem những câu hỏi đó.
manatwork

Bạn có thể cho chúng tôi một số ví dụ về các tiêu đề thất bại?
terdon

@terdon Hoàn toàn đúng. Tôi đã cập nhật câu hỏi để bao gồm một số tiêu đề ví dụ (với các địa chỉ email và ips khác nhau).
Mike B

Câu trả lời:


7

Điều này rất khó trong sed vì trong sed s/TMPHEADERS/"$HEADERS"/, giá trị của biến được thay thế bởi shell trước khi lệnh đạt đến sed, vì vậy các ký tự như thế &\/xuất hiện $HEADERScó ý nghĩa đặc biệt trong văn bản thay thế. Sed không có một cơ sở tra cứu biến.

Nhiệm vụ này khá dễ dàng với awk. Truyền HEADERSbiến trong môi trường:

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

hoặc như một biến awk:

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

3

Có một số khả năng:

sed Bạn sẽ phải thoát mọi char trong "$ Headers" để làm cho cuộc gọi sed an toàn.

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

BTW: Hoàn toàn không có lý do để gọi sed một lần cho mỗi thay đổi:

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

bash chính nó

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

@terdon Thật vậy, đó là biến sai. sed không mở rộng bất cứ điều gì (do sự thoát của mọi char trong biến). Ý anh là gì? Bạn đã thử điều này, nó không hoạt động?
Hauke ​​Laging

Thật tệ, tôi luôn trích dẫn sedcác lệnh của mình (tôi nghĩ điều đó là cần thiết) và các biến bash không được mở rộng (ý tôi là 's / foo / $ bar /' thực sự được in $barvà không phải là nội dung của biến). Lệnh của bạn hoạt động tốt mà không có dấu ngoặc kép (như bạn đã đăng) nó đã thất bại khi tôi đặt nó trong dấu ngoặc đơn. Xin lỗi, lực lượng của thói quen, miễn phí để quay trở lại chỉnh sửa của tôi.
terdon

Cảm ơn sự giúp đỡ nhanh chóng nhưng tôi đang gặp lỗi: sed: -e expression #1, char 121: unterminated s 'lệnh` Tôi đoán là tôi đã cấu hình sai lệnh: sed "s/TMPHEADERS/$HEADERS_ESCAPED/" /home/foo/scripts/fooalert/emailtemplate > /home/foo/scripts/fooalert/testing1234 Tôi đã xác nhận rằng tất cả các tiêu đề đã thoát đúng.
Mike B

@MikeB Bạn có thể tìm ra char gây ra vấn đề gì không? Tôi không chắc liệu có thể có một dòng mới trong văn bản thay thế hay không. Có thể $ HEADERS_ESCAPED chứa một dòng mới?
Hauke ​​Laging

1

Tôi không chắc tôi hiểu bạn muốn làm gì. Ví dụ: nếu bạn muốn thay thế chuỗi TMPHEADERSbằng danh sách dài thông tin tiêu đề bạn đã đăng, giải pháp Perl này có thể thực hiện:

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 

Tệp templatelà mẫu từ câu hỏi của bạn và tệp headercó dòng tiêu đề bạn đã đăng. Kết quả là

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

Bạn có thể mở rộng phần này cho hai bộ tiêu đề như sau:

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

Tôi tôn trọng câu trả lời này nhưng tiếc là tôi không biết rõ về perl đủ để duy trì nó trên cơ sở đang diễn ra. Tôi nhận ra rằng đó không phải là một câu trả lời hay (hoặc lý do không sử dụng mã hiệu quả hơn). Cảm ơn.
Mike B

1

Sử dụng m4bộ xử lý macro để thay thế TMPSOURCEIPTMPDATEvới những thứ được xác định trên dòng lệnh và TMPHEADERSvới bất cứ thứ gì có trong tệp headers.txt. Các mẫu là trong 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

Nếu bạn đã có các tiêu đề trong một biến, rõ ràng bạn có thể thay thế -DTMPHEADERS='include(headers.txt)'bằng -DTMPHEADERS="$headers".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.