如何遍历shell数组并使用jq从JSON文件中删除指定Slack频道条目
修正后的完整可用函数
exclude-inactive-channels () { # 参数合法性校验 if [ $# -ne 1 ]; then echo "请传入且仅传入channels.json文件路径作为参数" return 1 elif [ ! -f "$1" ]; then echo "文件不存在" return 1 fi cutoff_epoch=$(gdate -d "90 days ago" +'%s') inactive_channels=() # 筛选不活跃频道 for channel in $(jq -r '.[] | select(.is_archived == false) | .name' "$1"); do if [[ -d "$channel" ]]; then last_post=$(ls -1 "$channel" |sort -n |tail -1 |awk -F'.' '{print $1}') last_post_epoch=$(gdate -d "$last_post" +'%s') if [[ $last_post_epoch -lt $cutoff_epoch ]]; then inactive_channels+=("$channel") echo -n "移除$channel目录,最后发布时间为$last_post" #rm -rf "$channel" echo -e "\033[0;32m[OK]\033[0m" fi fi done echo "正在从$1中移除不活跃频道,结果写入new-$1" # 把shell数组转成jq可识别的JSON数组 inactive_json=$(printf '%s\n' "${inactive_channels[@]}" | jq -R . | jq -s .) # 单次jq调用完成过滤 jq --argjson inactive_list "$inactive_json" 'map(select(.name | IN($inactive_list[]) | not))' "$1" > "new-$1" # 兼容jq1.6以下版本的写法(如果上面的命令报错可以替换成下面这行) # jq --argjson inactive_list "$inactive_json" 'map(select(.name as $name | $inactive_list | index($name) | not))' "$1" > "new-$1" echo "正在用new-$1替换原文件$1" # mv "new-$1" "$1" }
核心改动说明
你原有代码的问题主要有两点:
- 重复读取原JSON文件、每次删单个频道再合并的逻辑容易出错,执行效率也低
- jq的
del用法错误,你需要的不是删除对象的name属性,而是过滤掉整个name匹配的数组元素 - 额外给所有变量加了双引号,避免路径含空格时出现异常
调用方式和你原来的写法完全一致:exclude-inactive-channels channels.json
内容的提问来源于stack exchange,提问作者Dustin
相关产品推荐
相关产品推荐

