在bash中查找并合并所有的package.json文件到jq中?

我怎样才能find所有的package.json文件,并在Bash中使用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:示例input和输出
让我们假设find3个package.json文件。 dependenciesdevDependencies是不同的,但必须结合:

find文件#1 …

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

find文件#2 …

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

find文件#3 …

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

…将全部合并为以下文件:

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

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

假设以下查找命令适用于您(如有必要,请进行调整)

 find ../../projects -name package.json 

这是一个解决scheme,它使用jq *运算符和reduce-s选项来合并对象:

 jq -s 'reduce .[] as $d ({}; . *= $d)' $(find ../../projects -name package.json) 

如果你喜欢,你可以轻松地连接文件并将它们发送到jq

 find ../../projects -name package.json -exec cat {} \; | \ jq -M -s 'reduce .[] as $d ({}; . *= $d)' 

正如我在回复你的评论中所指出的,如果你在makefile中这样做,你需要采取额外的步骤来处理$或者把你的filter放在一个文件中,并使用-f

如果你的jq有inputs ,这是比使用-s(“slurp”)选项更有效的解决scheme:

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

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

请记住在input中使用-n命令行选项,例如:

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

免减less的解决scheme

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

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

作为所有现在需要它的用户,仅供参考,我正在使用xargs和一个名为package-utils的实用程序来执行此操作。 jq东西比什么都要多。

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

 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 

我的总体目标是在Docker和Docker Compose中使用。 我正在使用它将一个解决scheme中使用的所有NPM模块预先caching在基础映像中。 基本上,它会创build一个在构build过程中使用的临时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 

这样就可以填充节点caching,所以基于这个映像的任何容器都能够安装caching中的大部分内容。

有一个原因,我正在做这个,而不是一个共同的node_modules卷,但这是一个不同的故事。