2016-04-10 37 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