2016-04-10 33 views
0

我有一個包含大約200萬個文件的文件夾。我需要運行下面的命令:如何結合多個sed和awk命令?

sed -i 's/<title>/<item><title>/g;s/rel="nofollow"//g;s/<\/a> &bull;/]]><\/wp:meta_value><\/wp:postmeta><content:encoded><![CDATA[/g;s/By <a href="http:\/\/www.website.com\/authors.*itemprop="author">/<wp:postmeta><wp:meta_key><![CDATA[custom_author]]><\/wp:meta_key><wp:meta_value><![CDATA[/g' /home/testing/* 

sed -i '$a]]></content:encoded><wp:status><![CDATA[draft]]></wp:status><wp:post_type><![CDATA[post]]></wp:post_type><dc:creator><![CDATA[Database]]></dc:creator></item>\' /home/testing/* 

awk -i inplace 1 ORS=' ' /home/testing/* 

我遇到的問題是,當我運行的第一個命令,它循環通過全部2個億個文件,然後我移動到第二個命令等。問題是我基本上總共要打開600萬次文件。

我更喜歡當每個文件打開時,所有3個命令都在它上面運行,然後它移動到下一個。希望這是有道理的。

+1

你考慮過[Perl](https://www.perl.org/)嗎? **正是這***是Perl存在的原因(IMO)。 –

+0

一個文件需要多長時間?也許你應該首先將你的文件夾分割成子文件夾/批處理文件。更多的CPU的一個系統,並希望並行處理?也許在不同的磁盤上。 –

+0

我想你會先做一個備份。 'sed -i'也會生成臨時文件。我會將輸出重定向到新文件。 –

回答

0

假設你的文件足夠小,單個文件放入內存作爲一個整體(並假設GNUsed,其中您使用的-i不帶選項參數的暗示):

sed -i -e ':a;$!{N;ba}; s/.../.../g; ...; $a...' -e 's/\n/ /g' /home/testing/* 

s/.../.../g; ...;$a...在上面的命令中表示您的實際替換和附加命令。

:a;$!{N;ba};作爲一個整體讀取每個輸入文件,然後執行所需的替換,附加和替換所有換行符,每個換行符都有一個空格。 [1]

這使您可以在每個輸入文件中使用一個sed命令。


[1]您awk 1 ORS=' '命令實際上與尾隨空間而不是一個新行創建輸出。相比之下,應用於整個輸入文件的's/\n/ /g'只會在行之間放置一個空格,並用換行符(假設輸入文件以一個結尾)終止整個文件。

1

您可以在一個awk命令所做的一切,就像這樣:

awk -i inplace -v ORS=' ' '{ 
    gsub(/<title>/,"<item><title>") 
    gsub(/rel="nofollow"/,"") 
    gsub(/<\/a> &bull;/,"]]><\/wp:meta_value><\/wp:postmeta><content:encoded><![CDATA[") 
    gsub(/By <a href="http:\/\/www.website.com\/authors.*itemprop="author">/,"<wp:postmeta><wp:meta_key><![CDATA[custom_author]]><\/wp:meta_key><wp:meta_value><![CDATA[") 
    print $0 "]]></content:encoded><wp:status><![CDATA[draft]]></wp:status><wp:post_type><![CDATA[post]]></wp:post_type><dc:creator><![CDATA[Database]]></dc:creator></item>" 
}' /home/testing/* 

但是,這並不意味着它一定是你想要的東西的最佳方式。

上面依賴於我正確地解釋你的命令正在做什麼,顯然未經測試,因爲你沒有提供任何樣本輸入和預期輸出。它仍然像原始腳本那樣依賴於GNU awk -i inplace