如何用Shell脚本(单行优先)实现/与\字符的双向替换?
问题:交换字符串中的
/ 和 \ 字符 先看示例变量的定义与输出:
$ a='/o\\' $ echo $a /o\\ $ b='\//\\\\/' $ echo $b \//\\/
需要实现一个名为 invert 的Shell单行命令,完成**将字符串中的 / 替换为 \,同时将 \ 替换为 /**的功能,执行后需得到如下结果:
$ invert "$a" \o/ $ invert "$b" /\\//\\
当前已有的sed方案需要借助临时字符(比如%),通过三次管道实现,不够简洁:
$ echo "$a" | sed 's#/#%#g' | sed 's#\\#/#g' | sed 's#%#\\#g' \o/ $ echo "$b" | sed 's#/#%#g' | sed 's#\\#/#g' | sed 's#%#\\#g' /\\//\\
该需求用于优化 git log --graph --all | tac 的输出显示(让较新的提交显示在底部)。
优化解决方案
方案1:用awk实现字符映射(无需临时字符)
awk支持在替换时做条件判断,直接完成双向替换:
invert() { echo "$1" | awk '{ gsub(/[\/\\]/, function(c) { return c == "/" ? "\\" : "/" }) } 1'; }
测试验证:
$ invert "$a" \o/ $ invert "$b" /\\//\\
方案2:Bash内置参数替换(无外部工具依赖)
利用Bash的内置字符串替换功能,用一个独特的临时标记完成转换,避免调用外部工具,效率更高:
invert() { local str="$1" str="${str//\//__TEMP_SLASH__}" # 先把/替换为临时标记 str="${str//\\//}" # 把\替换为/ str="${str//__TEMP_SLASH__/\\}" # 把临时标记替换回\ echo "$str" }
如果你的字符串可能包含__TEMP_SLASH__,可以换成更独特的标记,比如@@@SLASH@@@。
方案3:单行sed命令(用换行做临时标记)
利用换行作为临时标记(普通字符串中很少出现换行),单次sed调用完成替换:
invert() { echo "$1" | sed -e 's/\\/\/\n/g' -e 's/\//\\/g' -e 's/\n/\//g'; }
原理:先把所有\替换成/\n,再把所有/替换成\,最后把换行替换回/,完成双向交换。
内容的提问来源于stack exchange,提问作者lajarre
相关产品推荐
相关产品推荐

