将带有分隔符的多个文件合并到一个文件中

时间:2016-05-07 22:05:21

标签: json linux shell cat

我有几个(~300,000)单个JSON对象的文件,我想将它们组合成一个JSON数组的单个文件。我怎么能在linux上做这个,假设它们都位于"〜/ data_files"?

FILEA

{
  name: "Test",
  age: 23
}

FILEB

{
  name: "Foo",
  age: 5
}

FileC

{
  name: "Bar",
  age: 5
}

示例输出:(以括号开头和结尾,并在对象之间添加逗号)

[
    {
      name: "Test",
      age: 23
    },
    {
      name: "Foo",
      age: 5
    },
    {
      name: "Bar",
      age: 5
    }
]

我尝试过的事情:

我知道我可以使用cat来组合一堆文件,不知道如何对目录中的所有文件执行此操作,但试图解决这个问题。还试图弄清楚如何在文件之间,进行连接,还没有找到它的命令。

5 个答案:

答案 0 :(得分:5)

由于你似乎对unix有点新意,我会尝试给你一个简单的解决方案,并不会引入太多新概念。我会把巧妙和新颖留给其他海报。这个解决方案将非常高效,因为我所做的只是将文件流式传输到文件中。

首先,我们将在主目录中创建一个带有方括号的新文件。
echo "[" > ~/tmp.json

现在我们遍历data_files目录中的所有文件 并将它们附加到我们的新文件中。 >>会将它们添加到已经存在的内容中。如果您使用了>,那么每次都会覆盖该文件。 echo完成输出文件后,cat将添加逗号。
for i in ~/data_files/*; do cat $i;echo ","; done >> ~/tmp.json

所以现在我们将300k文件放在一个名为tmp.json的文件中,每个条目用逗号分隔,但文件的最后一行也是逗号,这不是我们想要的。
下面的sed命令的行为与cat类似,只是'$d'告诉它省略文件的最后一行。
所以我们创建一个新文件,除了我们的最后一行临时档案。
sed '$d' ~/tmp.json > ~/finished.json

我们需要关闭方括号
echo "]" >> ~/finished.json

最后我们删除了我们的临时文件 rm ~/tmp.json

我们完成了。

[
{
    name: "Test",
    age: 23
}
,
{
    name: "Foo",
    age: 5
}
,
{
    name: "Bar",
    age: 5
}
]

快速浏览一下关于漂亮打印json的this帖子,会指向一个命令行工具,它会将您的finished.json文件转换为完全您要求的输出

答案 1 :(得分:2)

一个简单的for循环和几个sed将会做

$ echo "[" > all; 
  for f in file{A,B,C}; 
  do 
     sed 's/^/\t/;$s/$/,/' "$f" >> all; 
  done; 
  sed -i '$s/,/\n]/' all

$ cat all
[
 {
   name: "Test",
   age: 23
 },
 {
   name: "Foo",
   age: 5
 },
 {
   name: "Bar",
   age: 5
 }
]

或与stdout相同

$ echo "["; for f in file{A,B,C}; do sed 's/^/\t/;$s/$/,/' "$f"; done |
sed `'$s/,/\n]/'`

运行目录中的所有文件,将file{A,B,C}更改为*

答案 2 :(得分:0)

即使文件数为300K +,此脚本仍应有效。此脚本也比sed解决方案更快,因为输入文件未被修改。

#!/bin/sh
tmp="/dev/shm/${USER}.find.tmp"
out='all.json'
find . -maxdepth 1 -name file\* > ${tmp}
echo '[' > ${out}
for f in $(head -n -1 ${tmp})
do
  cat ${f} >> ${out}
  echo ',' >> ${out}
done
f=$(tail -n 1 ${tmp})
cat ${f} >> ${out}
echo ']' >> ${out}
rm -f -- ${tmp}

答案 3 :(得分:0)

完整性的python版本:

import os, sys

dir = sys.argv[1]

print "["
for fn in os.listdir(dir):
    with open(dir + '/'  + fn, 'r') as f:
        read_data = f.read()
        print read_data,
    print ","
print "]"

答案 4 :(得分:0)

jc ..使用jq,这是或应该是最佳做法

$ cat <<eof | jq -s
> { "key": 1 }
> { "key2": 2 }
> { "key3": 3 }
> eof
[
  {
    "key": 1
  },
  {
    "key2": 2
  },
  {
    "key3": 3
  }
]

如果您的要求只是将json对象放入队列中,那么任何其他建议充其量都是幼稚的,这不是基于观点的陈述。