如何在Bash中计算两个逗号分隔应用列表的差集?
在Bash中过滤不同步应用列表的实现方法
假设我们有两个逗号分隔的应用列表:
out_of_sync_before_deployment="app1,app2,app3,app4," out_of_sync_now="app2,app5,app4,,"
需要从out_of_sync_now中移除所有在out_of_sync_before_deployment里出现过的应用,最终得到app5。以下是几种纯Bash的实现方式:
方法一:字符串替换+清理
通过逐个替换掉目标列表中存在的前置应用,再清理多余的空项和逗号:
# 处理前置列表,移除末尾逗号并分割为单行应用 before_list=$(echo "$out_of_sync_before_deployment" | sed 's/,$//' | tr ',' '\n') result="$out_of_sync_now" # 遍历每个前置应用,从结果中移除 for app in $before_list; do # 处理应用在开头、中间、结尾的情况 result=$(echo "$result" | sed "s/^$app,//; s/,$app,//; s/,$app$//; s/,$//") done # 清理空项并整理格式 final_result=$(echo "$result" | tr ',' '\n' | grep -v '^$' | tr '\n' ',') final_result=${final_result%,} # 移除末尾多余逗号 echo "$final_result"
方法二:数组遍历过滤
利用Bash数组存储两个列表,通过遍历检查元素是否存在于前置列表中:
# 将字符串转换为数组,处理逗号分隔符 IFS=',' read -ra before_arr <<< "$out_of_sync_before_deployment" IFS=',' read -ra now_arr <<< "$out_of_sync_now" # 过滤前置数组中的空元素 filtered_before=() for app in "${before_arr[@]}"; do [[ -n $app ]] && filtered_before+=("$app") done # 收集不在前置列表中的应用 result=() for app in "${now_arr[@]}"; do if [[ -n $app && ! " ${filtered_before[*]} " =~ " $app " ]]; then result+=("$app") fi done # 合并为逗号分隔的结果字符串 final_result=$(IFS=','; echo "${result[*]}") echo "$final_result"
方法三:管道+grep过滤
借助文本处理工具快速过滤,适合简洁实现:
# 处理前置列表,移除空行 before_lines=$(echo "$out_of_sync_before_deployment" | tr ',' '\n' | grep -v '^$') # 处理当前列表,过滤掉前置应用并整理格式 final_result=$(echo "$out_of_sync_now" | tr ',' '\n' | grep -v '^$' \ | grep -vFf <(echo "$before_lines") | tr '\n' ',') final_result=${final_result%,} echo "$final_result"
以上三种方法运行后都会输出app5,可根据实际场景选择合适的实现方式。
内容的提问来源于stack exchange,提问作者Robert Chen
相关产品推荐
相关产品推荐

