在bash中使用jq查找并合并所有package.json文件到一个文件?

时间:2017-08-14 18:51:42

标签: json node.js bash jq

如何在Bash中使用package.json找到所有jq个文件并将它们合并到一个文件中?以下代码段是我已经获得的,但追加文件:

find ../../projects -maxdepth 4 -type f -name "package.json" \
  -exec cat {} + | jq -s . > $(CURDIR)/node/.tmp/package.json

我尝试过使用'添加'但这似乎每次都会覆盖目标而不合并两者。

我的项目结构最初如下所示:

\ projects
  \ webapp
     \ package.json
  \ service
     \ package.json
  \ admin
     \ package.json
\ solutions
  \ killersolution
       Makefile
     \ node

应该make prenode后看起来像这样(见下文):

\ projects
  \ webapp
     \ package.json
  \ service
     \ package.json
  \ admin
     \ package.json
\ solutions
  \ killersolution
       Makefile
     \ node
        \ .tmp
          \ package.json   <- created

我正在使用Makefile启动此功能:

prenode:                                                                 
  @find ./node -type d -name ".tmp" -exec rm -rf {} +;                 
  @mkdir -p ./node/.tmp                                                
  @find ../../solutions -maxdepth 4 -type f -name "package.json" -exec cat {} + ... 

编辑#1:示例输入&amp;输出
我们假设找到了3个package.json个文件。 dependenciesdevDependencies不同,但必须合并:

找到文件#1 ......

{
  "name":"project-a",
  "dependencies":{
    "module-a":"1.2.3"
  }
}

找到文件#2 ......

{
  "name":"project-b",
  "dependencies":{
    "module-b":"2.3.4"
  }
}

找到文件#3 ......

{
  "name":"project-c",
  "devDependencies":{
    "gulp":"*"
  }
}

...将全部组合起来制作以下文件:

{
  "name":"project-c",
  "dependencies":{
    "module-a":"1.2.3",
    "module-b":"2.3.4"
  },
  "devDependencies":{
    "gulp":"*"
  }
}

*注: 最终输出文件中的name属性无关紧要。这里的关键是dependenciesdevDependencies对象的合并。

3 个答案:

答案 0 :(得分:1)

假设以下查找命令适合您(必要时进行调整)

#chat {
  position: fixed;
  bottom: 0;
  right: 0;
  width: 200px;
  background: #339;
  height: 150px;
}

#container {
  position: absolute;
  bottom: 50px;
  max-height: 100px;
  overflow-y: auto;
  width: 100%;
}

.message {
  background: grey;
  margin: 4px;
  width: fit-content;
}

input {
  position: absolute;
  margin: 12px;
  bottom: 0;
}

以下是使用jq <div id="chat"> <div id="container"> <div class="message">Hello</div> <div class="message">Hi there</div> <div class="message">How are you? What are you doing?</div> <div class="message">Surfin' the web</div> <div class="message">Haha, me toooo :o)</div> </div> <input placeholder="I'm useless" /> </div> 运算符以及 reduce find ../../projects -name package.json 选项合并对象的解决方案:

*

如果您愿意,可以轻松连接文件并将它们发送到jq

-s

如我在评论中的回复中所述,如果您在makefile中执行此操作,则需要采取额外步骤来处理$或将过滤器放入文件并使用jq -s 'reduce .[] as $d ({}; . *= $d)' $(find ../../projects -name package.json)

答案 1 :(得分:1)

如果你的jq有inputs,这里有一个比使用-s(“slurp”)选项更有效的解决方案:

reduce inputs as $i ({};
  .dependencies += ($i | .dependencies )
  | .devDependencies += ($i | .devDependencies ) )

这也会产生“干净”的结果(即没有“名称”字段)。

请记住在inputs中使用-n命令行选项,例如沿着这条线:

jq -n -f program.jq $(find ...)

无还原溶液

如果你的jq没有inputs,当与“-s”命令行选项一起使用时,这是一个无减少的解决方案:

map([.dependencies, .devDependencies])
| transpose
| map(add)
| {dependencies: .[0], devDependencies: .[1]}

答案 2 :(得分:0)

作为现在需要它的任何人的FYI,我目前正在使用xargs和名为package-utils的实用程序执行此操作。 <{1}}更像是想要而不是任何东西。

这是当前的makefile,如果你想使用它:

jq

我的总体目标是在Docker和Docker Compose中使用。我用它来预先缓存基础映像中的单个解决方案中使用的所有NPM模块。基本上,它会创建一个在构建过程中使用的临时prenode: @find $(CURDIR)/node -type d -name ".tmp" -exec rm -rf {} +; @mkdir -p $(CURDIR)/node/.tmp @find ../../projects -type f -name "package.json" -maxdepth 4 -print0 | xargs -0 package-merge > $(CURDIR)/node/.tmp/package.json 文件。

我的package.json内容如下:

Dockerfile

这允许填充节点缓存,因此基于此映像的任何容器都可以从缓存中安装大部分内容。

我正在这样做的原因,而不是COPY ./.tmp/package.json /var/www/package.json VOLUME /var/www VOLUME /var/www/node_modules WORKDIR /var/www RUN npm install RUN rm package.json 的常见卷,但这是一个不同的故事。