Shell脚本实现子串查找替换:存在则替换,不存在则添加
解决文件中指定子串的替换/追加需求
我来帮你搞定这个问题!你需要的是针对特定前缀的字符串做“存在则替换、不存在则追加”的操作,用grep+sed的组合就能完美实现,而且能处理所有匹配项,不只是第一个。
完整脚本实现
#!/bin/bash # 定义参数,方便后续修改 TARGET_PREFIX="foo_eusa" NEW_ITEM="foo_eusa.r4" FILE_PATH="my_file.txt" # 检查文件中是否存在以TARGET_PREFIX开头的项(带.作为分隔) if grep -q "\b${TARGET_PREFIX}\." "$FILE_PATH"; then # 存在则全局替换所有匹配项:把TARGET_PREFIX.rX替换成NEW_ITEM # 注意:如果是macOS系统,sed -i 需要加空参数,写成 sed -i "" "s/..." sed -i "s/\b${TARGET_PREFIX}\.r[0-9]\+/${NEW_ITEM}/g" "$FILE_PATH" else # 不存在则将新项追加到文件末尾 echo "$NEW_ITEM" >> "$FILE_PATH" fi
关键部分解释
检查匹配项:
grep -q "\b${TARGET_PREFIX}\." "$FILE_PATH"-q让grep只返回匹配状态,不输出内容;\b是单词边界,确保我们匹配的是完整的foo_eusa.前缀,不会误匹配类似foo_eusaxyz这种无关字符串;\.转义点号,避免它被当作正则通配符。
全局替换:
sed -i "s/\b${TARGET_PREFIX}\.r[0-9]\+/${NEW_ITEM}/g"-i实现原地修改文件(不用生成临时文件);- 正则
${TARGET_PREFIX}\.r[0-9]\+精准匹配foo_eusa.r后面跟任意数字的完整项; /g标记表示全局替换,文件里所有符合的项都会被替换,而不是只替换第一个。
追加新项:如果grep没找到匹配项,就用
echo >>把新字符串追加到文件末尾,不会破坏原有内容。
测试示例
假设你的my_file.txt初始内容是:
foo_eusa.r1 foo_chnc.r5 foo_deu.r10
运行脚本后,内容会变成:
foo_eusa.r4 foo_chnc.r5 foo_deu.r10
如果初始文件里没有任何foo_eusa相关项,比如:
foo_chnc.r5 foo_deu.r10
运行脚本后会追加新项,变成:
foo_chnc.r5 foo_deu.r10 foo_eusa.r4
内容的提问来源于stack exchange,提问作者Tinku




