我有多个大文件(2-4gb),我想对它进行一些简单的操作。整个文件都在一行中,这让我想知道如何对它执行sed操作。
我想对每个文件做三件事:
1)删除所有[
个字符
2)删除所有]
个字符
3)将所有},{
替换为}{
。
到目前为止,我已尝试使用sed -e 's/},{/}{/g' file.json > file_new.json
选项g
,但没有运气。我也试过sed -e 's/\[//g' file.json > file_new.json
没有运气。我只得到一个重复的文件。
有什么想法吗?
答案 0 :(得分:3)
使用gnu awk:
awk 'BEGIN{FS="},{";OFS="}{";RS="[][]";ORS=""}$1=$1' file
使用perl (必须经过测试):
可能更快perl -0135 -pe 's/},{/}{/g;y/][//d' file
其中135代表八进制中的字符]
。 -0选项定义记录分隔符(而不是逐行读取,文件由各部分读取,直到每个]
)
这两个脚本的目标是避免将整个文件加载到内存中。
将结果存储在文件中:
您可以重定向输出。
awk 'BEGIN{FS="},{";OFS="}{";RS="[][]";ORS=""}$1=$1' file > result
或
perl -0135 -pe 's/},{/}{/g;y/][//d' file > result
您可以使用命令行选项:
awk -i inplace -v INPLACE_SUFFIX=.bak 'BEGIN{FS="},{";OFS="}{";RS="[][]";ORS=""}$1=$1' file
或
perl -0135 -pi'*.bak' -e 's/},{/}{/g;y/][//d' file
(这两个命令会创建原始文件的备份,添加扩展名.bak,如果要更改源文件,请删除-v INPLACE_SUFFIX=.bak
以获取gawk,并'*.bak'
的Perl。)
答案 1 :(得分:1)
当我有这样庞大的单行文件时,通常的基于行的工具无效,我通常转向:tr
!
1)删除所有[字符
2)删除所有]字符
这很简单:
tr -d '[]' < file > strippedfile
(这可能不适用于真正的,非常古老的SysV版本的tr,但对任何现代版本都应该没问题。)
3)替换所有出现的},{with} {。
这更棘手,因为你关心上下文,所以它真的是sed
的工作。我使用过的一个问题是使用tr
暂时将其他字符更改为换行符 - 也就是暂时将巨大的单行文件更改为多行文件 - 然后运行{{1最后将其更改回单行文件。像
sed
如果原始文件包含 no 换行符,则此最后一个仅。您可以先运行tr '{' '\n' < file | sed 's/},$/}/' | tr '\n' '{' > newfile
以确定。
答案 2 :(得分:0)
尝试将换行符放在文件的末尾:
procedure frmMyForm.onSpeedButtonsClick(Sender: TObject);
begin
if TSpeedButton(Sender).Tag <> 0 then Exit;
TSpeedButton(Sender).Tag := 1;
if Sender = btn1 then btn2.Tag := 0
else btn1.Tag := 0;
// code that runs when the `Down` state changes ...
end;
许多UNIX工具根本无法识别没有结尾换行符的文件作为文本文件,因此不会对它们进行操作,因此可能是您的问题。如果这不起作用,请编辑您的问题,以包含文件的简洁,可测试的示例。