2016-11-20 80 views
0

說我有一個這樣的文件:循環sed腳本內不會終止

... 
{ 
    ... 
    cout<< "---at time:\t\t"<< sc_core::sc_time_stamp()<<"\n\n" << endl; 
    ... 
    cout<< "---at time:\t\t"<< sc_core::sc_time_stamp()<<"\n\n" << endl; 
    ... 
} 
... 
{ 
    ... 
    if(strcmp(argv[1], "--io_freq1_Mhz") != 0) 
    if(strcmp(argv[2], "--io_freq2_Mhz") != 0) 
    ... 
    if(strcmp(argv[11], "--bytes_per_word") != 0) 
    ... 
    if(strcmp(argv[23], "--mem_size_bytes") != 0) 
    ... 
} 

我想要做的首先是,使用SED,加載含圖案的 「--foo」 到所有行模式空間並打印出來只是paranthesis內的部分,所以我用命令:

sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file 

這不正是我想要的東西,所以我得到作爲輸出:

--io_freq1_Mhz 
--io_freq2_Mhz 
... 
--bytes_per_word 
... 
--mem_size_bytes 

接下來我想合併所有的行到一個空白的內容。我可以解決這個使用命令替換:

echo `sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file` 

這給了我:

--io_freq1_Mhz --io_freq2_Mhz --... --bytes_per_word --... --mem_size_bytes 

接下來,我要插入一些betwenn的參數,例如1,所以最終的結果應該是這樣的:

--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... 1 --bytes_per_word 1 --... 1 --mem_size_bytes 1 

我幾乎可以解決這個問題。我使用的命令:

echo `sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1/p' file` | sed -n -e ':start { s/\(--[^\ ]*\) -/\1 1 -/p; b start }' | sed -n -e 's/\(--.*[^\ ]\)/\1 1/p' 

,但我得到兩個小問題。首先,我跳回到我開始前標記輸出被管道輸送到最後SED聲明,這意味着我得到作爲輸出:

--io_freq1_Mhz 1 --io_freq2_Mhz --... --bytes_per_word --... --mem_size_bytes 1 
--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... --bytes_per_word --... --mem_size_bytes 1 

等。所以我的第一個問題是,我怎樣才能避免每次輸出到最後的sed語句中。我可以使用不同的sed選項/標誌來實現這一點嗎?

第二個問題是,命令沒有終止。迭代與

--io_freq1_Mhz 1 --io_freq2_Mhz 1 --... --bytes_per_word 1 --... --third_last_item 1 --second_last_item mem_size_bytes 1 

結束。如可以看到的,第二最後一個項目後面的「1」不追加並且另外整個命令不會終止。我必須使用Ctrl-C來終止它。

+1

符號'''echo'sed ... file' | sed ...'''很糟糕。你應該使用'''sed ... file | sed ...'''。您按順序運行3個sed命令;應該簡化爲一個,或者應該使用'awk'(或Perl或Python)來代替。 –

+0

歡迎使用堆棧溢出。 請注意,在這裏說'謝謝'的首選方式是通過 提高投票的好問題和有用的答案(一旦你有足夠的聲譽這樣做),並接受任何 問題最有用的答案,你問(這也給你一個小小的提升,以你的聲望 )。 請參閱[關於]頁面,以及[如何在此處提問 ?]和 [當有人回答我的 問題時,我該怎麼辦? ?](http://stackoverflow.com/help/someone-answers) –

回答

1

使用稍作修改你的第一個命令:

sed -n -e 's/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/\1 1/p' file | tr '\n' ' ' 

已經提取的名字,隨後將其追加數字。 tr命令將換行符轉換爲空格。你可以在sed;它會很煩瑣,就是這樣。


其實,這是不是所有的更加繁瑣,但它需要尋找的過程中以不同的方式。具體而言,需要匹配的模式保存在貨艙空間,然後處理它們在輸入的末尾:

sed -n \ 
    -e '/.*[^-]\(-\{2\}[^-].*\)"\(.*\)/{ s//\1 1/; H; }' \ 
    -e '$ { x; s/\n/ /g; p; }' file 

}字符前的分號是必要的BSD(MacOS的)sed,但不與GNU sed。第一個-e選項會查找與您的模式相匹配的行,然後將替代命令應用於該行以僅保留--name部分加上數字1,然後將該信息附加到換行符後的保留空間。第二個-e選項適用於最後一行。它交換模式並保留空格,然後用空格替換每一個換行符並打印結果,包括尾部換行符,腳本用tr代替空白。

輸出(注意前導空白):

--io_freq1_Mhz 1 --io_freq2_Mhz 1 --bytes_per_word 1 --mem_size_bytes 1 

如果你不想前導空白,打印(在p前添加s/^ //;)之前將其刪除。

+0

謝謝,這工作。所以,我假設我以複雜的方式嘗試了它;-)。至少我學到了... – FloHe

+0

@FloHe:看到更新 - 我的第一個解決方案使用兩個命令,其中一個就足夠了。 –