我有一个包含大约200万个文件的文件夹。我需要运行以下命令:
sed -i 's/<title>/<item><title>/g;s/rel="nofollow"//g;s/<\/a> •/]]><\/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/*
我遇到的问题是,当我运行第一个命令时,它会遍历所有200万个文件,然后继续执行第二个命令,依此类推。问题是我基本上不得不打开600万次文件。
我更喜欢在打开每个文件时,所有3个命令都在其上运行,然后继续运行到下一个文件。希望这是有道理的。
答案 0 :(得分:1)
您可以在一个awk命令中执行以下操作:
awk -i inplace -v ORS=' ' '{
gsub(/<title>/,"<item><title>")
gsub(/rel="nofollow"/,"")
gsub(/<\/a> •/,"]]><\/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/*
但这并不意味着它必然是做你想做的最好的方式。
上面依赖于我正确解释你的命令正在做什么,并且显然未经测试,因为你没有提供任何样本输入和预期输出。它仍然依赖于-i inplace
的GNU awk,就像你的原始脚本一样。
答案 1 :(得分:0)
假设您的文件足够小,单个文件可以整合到内存中(并假设 GNU sed
,您使用-i
时没有选项-argument暗示):
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'
只会在行之间放置一个空格,并使用换行符终止整个文件(假设输入文件以一个结尾)。功能