2011-10-20 34 views
1

我具有其中存在具有共同串certian行文件中的文本:替換前後串

_report_file << 

SO解決此上面的文字可以是任何thingbut它與semiclon(;)結束 對於例如參見下面的行:

CACUP_updater::_report_file << "The job has terminated." << endl; 

線的另一個示例可以是:

_report_file << "The job is reading." << endl; 

我需要追加abc;預字符串和xyz;作爲後串到該行,使線條看起來像

abc;CACUP_updater::_report_file << "The job has terminated." << endl;xyz; 

基本上,我想搜索"_report_file <<",選擇完整產品線和前期和後期追加一些文本。我如何在sed或perl或awk中執行此操作。

+0

我已經更新了我的答案相匹配的更新問題。我比你提出的更系統地解釋了這個問題,我期望它適合你的情況。 – sehe

回答

0

編輯以迴應您的更新問題。我想你就錯了:)

我建議你做它,而不是這樣:

#!/usr/bin/perl 
use strict; 
use warnings; 

while(<>) 
{ 
    s/([\w]+::)?_report_file\s*<<\s*(.*);/CACUP_REPORT($2);/go; 
    print 
} 

這樣的話,你可以在C++中,這樣定義一個宏

#define CACUP_REPORT(message) do { \ 
    /* abc; */ \ 
    ::CACUP_updater::_report_file << message; \ 
    /* xyz; */ } while (false) 

但爲什麼?

  • 你可以閱讀所有關於安全宏別處

  • 您獲得更多的靈活性。您稍後可以在一個點上更改所有實例。

  • 可以委託給一個函數

  • 你可以聲明臨時stringstream並寫入結果的文本到一個整體的其他媒介(網絡?使用fwrite?內存緩衝區?兩個流?)。

  • 您可以根據全局falg進行日誌記錄,而不必通過代碼複製檢查。

那麼你得到它:它幾乎是DRYprinciple

樣品輸入:

#include <iostream> 
using namespace std; 

namespace CACUP_updater 
{ 
    std::ostream& _report_file = std::cout; 

    void start_reading() 
    { 
     _report_file << "The job is reading." << endl; 
    } 
} 

int main() 
{ 
    CACUP_updater::_report_file << "The job is starting." << endl; 
    CACUP_updater::start_reading(); 
    CACUP_updater::_report_file << "The job has terminated." << endl; 
} 

示例輸出:

的結果,例如perl -i.bck test.cpp

#include <iostream> 
using namespace std; 

namespace CACUP_updater 
{ 
    std::ostream& _report_file = std::cout; 

    void start_reading() 
    { 
     CACUP_REPORT("The job is reading." << endl); 
    } 
} 

int main() 
{ 
    CACUP_REPORT("The job is starting." << endl); 
    CACUP_updater::start_reading(); 
    CACUP_REPORT("The job has terminated." << endl); 
} 

的一些想法宏的實現:

這顯示瞭如何

  • 使用臨時流字符串化
  • 打印更比一個輸出流,有條件地
  • ha ndle例外正確內聯
  • 添加日期時間戳(僅適用於寫入日誌文件,而不是標準錯誤),當然
  • ,有足夠多的房間,以適應任何abc;xyz;你心目中:)

#include <iostream> 
#include <sstream> 
#include <fstream> 

using namespace std; 

static bool _verbose = false; 

#define CACUP_REPORT(message) do { \ 
    std::stringstream ss; \ 
    ss << message; \ 
    ::CACUP_updater::log_helper(ss.str()); \ 
    } while (false) 

namespace CACUP_updater 
{ 
    std::string getdatetime() { return "YYYY/MM/DD - HH:MM:SS.mmm"; } // demo only 
    void log_helper(const std::string& msg) 
    { 
     try 
     { 
      std::ofstream ofs("/tmp/myprogram.log", std::ios_base::app); 

      ofs << getdatetime() << "\t" << msg; 
      ofs.flush(); 
      ofs.close(); 

      // log errors always to stderr, 
      // and all other messages if verbose is set 
      if (_verbose || std::string::npos != msg.find("ERROR")) 
       std::cerr << msg << std::endl; 
     } catch(std::exception& e) 
     { 
      std::cerr << "Unhandled error writing to log: '" << e.what() << std::endl; 
     } 
    } 

    void start_reading() 
    { 
     CACUP_REPORT("The job is reading." << endl); 
    } 
} 

int main() 
{ 
    CACUP_REPORT("The job is starting." << endl); 
    CACUP_updater::start_reading(); 
    CACUP_REPORT("The job has terminated." << endl); 
} 

輸出到文件是:

YYYY/MM/DD - HH:MM:SS.mmm The job is starting. 
YYYY/MM/DD - HH:MM:SS.mmm The job is reading. 
YYYY/MM/DD - HH:MM:SS.mmm The job has terminated. 

輸出到標準錯誤依賴於verbose標誌


想像會發生什麼,如果if (b) _report_file << "ok!" << std::endl;

注意備份文件被創建:test.cpp.bck

+0

我已更新我的問題,請參閱編輯 – Vijay

+0

@RahulDravid:我以全面的方式解決您的編輯問題(我還爲所有的鈴聲和​​哨聲實現您自己的記錄器宏添加了靈感)。希望你喜歡它 – sehe

+0

我不是'CACUP_REPORT(「作業已經終止。」<< endl)的大粉絲;' - 這看起來不像C++中的括號裏面的'<<'。當然,有足夠的運算符重載,可以是有效的獨立代碼,但我建議它太鈍了。 – Tanktalus

0
$ perl -i.bak -n -e 'print "abc;${_}xyz;"' your_file_here 

這會給你的文件的備份副本了。

+0

我已更新我的問題請參閱編輯 – Vijay

0
awk '/_report_file <</{$0="abc;" $0 "xyz;"}{print}' 
+0

我想這隻會打印行其中字符串不是其餘行。 – Vijay

1

一個Perl方式:

perl -anE 'chomp;s/^(.*?::_report_file <<.*;)$/abc;$1xyz;/;say;' foo.txt > foo2.txt 

perl -ane 'chomp;s/^(.*?::_report_file <<.*;)$/abc;${1}xyz;/;print "$_\n";' foo.txt > foo2.txt 
0
perl -pi.bak -e 's{.*_report_file <<.*}{abc;$&xyz;}' file_name_here