在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
文件。 dependencies
和devDependencies
是不同的,但必须结合:
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
属性是不相关的。 这里的关键是dependencies
和devDependencies
对象的合并。
假设以下查找命令适用于您(如有必要,请进行调整)
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
卷,但这是一个不同的故事。