You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Shell脚本中根据字符串匹配删除JSON数组元素?

在Shell中删除JSON数组里匹配指定字符串的元素

嘿,这个需求用jq就能完美解决——这是Shell环境下处理JSON数据的标配工具,比自己写字符串切割靠谱多了。我给你一步步演示怎么实现:

前提准备

首先确保你的系统已经安装了jq,大部分主流系统都能通过包管理器快速安装:

# Debian/Ubuntu 系列
sudo apt-get install jq

# RHEL/CentOS 系列
sudo yum install jq

# macOS 用 Homebrew
brew install jq

基础实现示例

假设你的JSON数组已经存在变量里,或者保存在文件中,我们可以用jq的map+select组合来精准筛选元素:

1. 从变量直接处理

先定义原始的JSON输入:

json_input='["https://test-ci.cmxdev.com/dev/AD-885/?oauth=callback", "https://test-ci.cmxdev.com/dev/INS-1676-a/?oauth=callback", "https://test-jdtest.cmxdev.com?oauth=callback", "https://localhost:3000?oauth=callback"]'

要删除包含INS-1676-a的元素,执行以下命令即可:

echo "$json_input" | jq 'map(select(. | contains("INS-1676-a") | not))'

2. 从文件读取处理

如果JSON数组保存在input.json文件中,可以直接读取文件处理,并将结果输出到新文件:

jq 'map(select(. | contains("INS-1676-a") | not))' input.json > output.json

核心命令拆解

让我解释一下关键的jq表达式map(select(. | contains("INS-1676-a") | not)):

  • map():遍历数组中的每一个元素
  • select():只保留符合条件的元素
  • . | contains("INS-1676-a") | not:对当前元素,先检查是否包含目标字符串,再取反——也就是保留不包含目标字符串的元素

更灵活的动态写法

如果需要动态指定要匹配的字符串,用--arg参数传递变量更安全,能避免字符串转义的坑:

#!/bin/bash

# 可替换为你需要匹配的目标字符串
target="INS-1676-a"

json_input='["https://test-ci.cmxdev.com/dev/AD-885/?oauth=callback", "https://test-ci.cmxdev.com/dev/INS-1676-a/?oauth=callback", "https://test-jdtest.cmxdev.com?oauth=callback", "https://localhost:3000?oauth=callback"]'

# 处理JSON数组
result=$(echo "$json_input" | jq --arg t "$target" 'map(select(. | contains($t) | not))')

# 输出结果
echo "处理前:"
echo "$json_input"
echo -e "\n处理后:"
echo "$result"

运行这个脚本,你会得到预期的输出:

处理前:
["https://test-ci.cmxdev.com/dev/AD-885/?oauth=callback", "https://test-ci.cmxdev.com/dev/INS-1676-a/?oauth=callback", "https://test-jdtest.cmxdev.com?oauth=callback", "https://localhost:3000?oauth=callback"]

处理后:
[
  "https://test-ci.cmxdev.com/dev/AD-885/?oauth=callback",
  "https://test-jdtest.cmxdev.com?oauth=callback",
  "https://localhost:3000?oauth=callback"
]

进阶:正则精准匹配

如果需要更精确的匹配规则(比如匹配特定前缀、后缀或复杂模式),可以用test()函数结合正则表达式:

# 删除以"https://test-ci.cmxdev.com/dev/INS-1676-a/"开头的元素
echo "$json_input" | jq 'map(select(. | test("^https://test-ci.cmxdev.com/dev/INS-1676-a/") | not))'

内容的提问来源于stack exchange,提问作者Jayesh Dhandha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:33:08