如何将文本文件拆分成多个文件并从行前缀中提取文件名?

时间:2017-08-29 12:37:45

标签: json linux bash awk

我有一个简单的日志文件,内容如下:

1504007980.039:{"key":"valueA"}
1504007990.359:{"key":"valueB", "key2": "valueC"}
...

我希望输出到多个文件,每个文件都包含时间戳之后的JSON部分作为内容。所以我会得到文件:

1504007980039.json
1504007990359.json
...

这与How to split one text file into multiple *.txt files?类似,但文件名应从每一行中提取(并删除一个额外的点),而不是通过索引生成

最好我想要一个可以用bash执行的单行。

2 个答案:

答案 0 :(得分:2)

由于你没有使用GNU awk,你需要关闭输出文件,以避免过多的打开文件"错误。为避免这种情况,并在输出重定向期间出现JSON中的特定值以及与未定义行为相关的问题,这就是您所需要的:

awk '{
    fname = $0
    sub(/\./,"",fname)
    sub(/:.*/,".json",fname)
    sub(/[^:]+:/,"")
    print >> fname
    close(fname)
}' file

如果你看到一些好处,你当然可以把它挤到一行:

awk '{f=$0;sub(/\./,"",f);sub(/:.*/,".json",f);sub(/[^:]+:/,"");print>>f;close(f)}' file

答案 1 :(得分:1)

awk 解决方案:

awk '{ idx=index($0,":"); fn=substr($0,1,idx-1)".json"; sub(/\./,"",fn); 
       print substr($0,idx+1) > fn; close(fn) }' input.log 
  • idx=index($0,":") - 捕获第一个:的索引

  • fn=substr($0,1,idx-1)".json" - 准备文件名

查看结果(来自问题的2个样本行):

for f in *.json; do echo "$f"; cat "$f"; echo; done

输出(文件名 - > 内容):

1504007980039.json
{"key":"valueA"}

1504007990359.json
{"key":"valueB"}