如何使用jq删除composer.json中匹配指定字符串的嵌套条目
jq删除composer.json指定依赖方案
问题背景
开发、生产环境切换场景下,需要用jq编辑composer.json,移除require字段下匹配指定规则的依赖项。原有通过to_entries实现筛选的方案会破坏JSON原有结构,且无法正确执行删除操作。
问题复现
示例composer.json
{ "name": "laravel/laravel", "type": "project", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "require": { "php": "^8.0", "kreait/laravel-firebase": "^4.1", "laravel/cashier-paddle": "^1.5", "laravel/framework": "^8.75", "laravel/sanctum": "^2.11", "laravel/socialite": "^5.5", "laravel/tinker": "^2.5", "livewire/livewire": "^2.5", "lorisleiva/laravel-actions": "^2.4", "owenvoke/blade-fontawesome": "*", "protonemedia/laravel-verify-new-email": "^1.5", "pusher/pusher-php-server": "^7.0", "rapidstatic/rapidstatic": "dev-master", "rapidstatic/scraper": "dev-master", "razorui/blade-application-ui": "^0.3.0" } }
原有错误命令
jq '.require | to_entries | map(select(.key | contains("rapidstatic")))' composer.json
原有命令输出
输出仅返回筛选到的条目,将原对象转为了key/value结构的数组,破坏了composer.json的完整结构:
[ { "key": "rapidstatic/rapidstatic", "value": "dev-master" }, { "key": "rapidstatic/scraper", "value": "dev-master" } ]
正确实现方案
不需要将对象转为entry数组,直接使用del函数搭配路径匹配即可删除目标依赖,全程保留原JSON结构:
预览修改结果(不修改源文件)
jq 'del(.require[keys[] | select(contains("rapidstatic"))])' composer.json
原地修改源文件
jq -i 'del(.require[keys[] | select(contains("rapidstatic"))])' composer.json
命令逻辑说明
- 操作全程在原JSON结构上执行,不会改动
require外的其他顶层字段,也不会将对象转为数组破坏格式 keys[]遍历require字段下所有依赖包名,通过select(contains("rapidstatic"))筛选出需要删除的目标包del()函数直接删除匹配路径对应的键值对,输出结果完全符合composer.json的原有结构规范
执行后效果
两个rapidstatic/*依赖会被从require中移除,其余内容完全保留:
{ "name": "laravel/laravel", "type": "project", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "require": { "php": "^8.0", "kreait/laravel-firebase": "^4.1", "laravel/cashier-paddle": "^1.5", "laravel/framework": "^8.75", "laravel/sanctum": "^2.11", "laravel/socialite": "^5.5", "laravel/tinker": "^2.5", "livewire/livewire": "^2.5", "lorisleiva/laravel-actions": "^2.4", "owenvoke/blade-fontawesome": "*", "protonemedia/laravel-verify-new-email": "^1.5", "pusher/pusher-php-server": "^7.0", "razorui/blade-application-ui": "^0.3.0" } }
扩展匹配规则
只需修改select()内的判断逻辑,即可适配不同的筛选需求:
- 筛选版本为
dev-master的包:select(. == "dev-master") - 筛选包名以
laravel/开头的包:select(startswith("laravel/")) - 同时匹配多个关键词:
select(contains("rapidstatic") or contains("dev-"))
内容的提问来源于stack exchange,提问作者BlakeyUK
相关产品推荐
相关产品推荐

