linux下sed命令在windows上的移植版本工具sed.exe linux下的sed命令处理字符串很方便,这是一个在windows上可以使用的版本,下载之后就可以在windows上使用sed命令了。 今天写这篇记录要解决的问题来源于最近一名读者的提问,之前写过一篇名为《.bat批处理(六):替换字符串中匹配的子串》的总结文章,结果有读者在评论区提问说,如果想要替换的子串中包含等号 在尝试多次失败之后,我意识到事情远没有想象的那么简单,开始在网上寻找解决方案,结果有些让人意外,绝大多数人都说这是 看了上面的叙述,可能有些小伙伴对我所说的问题还没有太直观的认识,接下来我们举个例子来说一下这个问题究竟是怎样产生的。 首先需要被替换的字符串中要包含等号,我们来定义一个这样的变量: 变量的名字是 确定一下我们想要替换的子串 运行之后的结果是: abcdo=A=o=Acar12a=ajdjko=A=o=At 和我们想法不一样,我们本来想把 很多语言中都有转义字符,比如 Markdown 语法中的反斜杠 在批处理中也有转义字符的概念,它就是 我们就利用这个转义字符来告诉替换命令,被替换的子串中的 运行之后结果如下: abcdo=ocar12a=ajdjko=ot 与替换前对比发现没有任何变化,看来转义字符的想法没能帮助我们解决问题,还是想想其他的办法吧。 既然 既然要一个个的字符去判断,就需要遍历原字符串,最简单的可以使用字符串分割啊,语法为 具体的思路就是我们先判断第一个字符,如果是 需要使用 source string is abcdo=ocar12a=ajdjko=ot 事情到了这里好像还没完,在实际操作中有些情况不是替换一个 既然 这步替换可能最后需要还原的,所以要求我们替换成的目标序列不能在原串中出现,比如我们上面把 这个序列我们可以定义的变态一点,比如把 我们之前要查找替换的子串是 其实就是把第1步替换完结果作为原串,把其中的 这一步就是处理那些虽然是 步骤梳理清楚了,下面来写代码,按照步骤一步步写就可以了: 运行之后的结果为: source1 string is abcdo=ocar12a=ajdjko=ot 这次终于替换成功了, 时间慢慢地磨去了年少轻狂,也渐渐地沉淀了冷暖自知。
文章目录
前言
=
,那么就无法替换了,问有没有什么办法可以解决。遇到这个问题的第一感觉应该挺好处理的吧,如果批处理程序在替换操作中认为等号 =
比较特殊,那就加个转义字符应该就可以了,但事实却证明这种想法有些天真了。SET
命令的执行规则决定的,无法实现这种需求。当要替换的子串中包含 =
时,第一个 =
就会被认为是替换语法中的 =
,进而导致无法得到正确的结果,即使是使用转义字符都无法完成正确替换,加入的转义字符会影响匹配,导致替换失败。还有一些人建议用其他工具来完整这种需求,比如记事本的替换功能 O(∩_∩)O
。遇到的问题
0x00 带有 = 的字符串
set STR=abcdo=ocar12a=ajdjko=ot
STR
,变量的值是 abcdo=ocar12a=ajdjko=ot
,其中包含了三个 =
。0x01 带有 = 的想要被替换的子串
o=o
,假如我们想把它替换成字母 A
,按照一般的替换规则X:Y=Z
,在 X
串中寻找到 Y
串之后把它替换成 Z
串,实现的代码如下:@echo off set STR=abcdo=ocar12a=ajdjko=ot set RESULT=%STR:o=o=A% echo %RESULT% pause > nul
o=o
替换成 A
,但是从结果来看应该是把 o
替换成了 o=A
,原因就是我们选择的被替换中的子串 o=o
包含一个 =
,而这个 =
被当成了替换语法 X:Y=Z
中的 =
,所以就不对了。0x02 尝试用转义字符来处理
,在 Markdown 语法中被星号
*
包裹的文字是倾斜的,但是如果想正常的输出一个 *
怎么办呢?就需要在 *
前面加一个反斜杠 ,变成
*
,这样 *
原本的倾斜文字的作用就被转义了,变成了一个普通的输出字符。^
,我们知道在批处理中 >
、|
等符号都是有特殊用处的,所以不能简单的输出,比如 echo >
是无法输出一个大于号的,要写成 echo ^>
才能正常输出一个 >
符号。=
是一个普通字符,不能作为替换规则的一部分,所以被替换的子串写成了 o^=o
,我们实现下面的代码,看看能不能达到目的:@echo off set STR=abcdo=ocar12a=ajdjko=ot set RESULT=%STR:o^=o=A% echo %RESULT% pause > nul
稳扎稳打的解决方案
=
这么特殊,我们就先想办法干掉等号,直接替换的方式不好使,我们可以一个字符一个字符的判断啊,虽然麻烦一点,但是解决问题才是最重要的。原串:~偏移,长度
就可以了,如果不太清楚可以参考一下 《.bat批处理(三):变量声明、设置、拼接、截取》,截取第一个字符的语法是 原串:~0,1
, 截取第二个字符的语法是 原串:~1,1
,以此类推。=
就进行替换,如果不是 =
就放到结果字符串里,然后继续判断第二个字符进行操作,最后所有的字符处理一遍就完成了替换。goto
语句来写一个循环,代码逻辑比较简单,就是遍历所有字符,是 =
就替换,不是 =
就保留,假设我们先把 =
替换成 #
,实现的代码如下:@echo off set STR=abcdo=ocar12a=ajdjko=ot set CURSTR=%STR% set RESULT= :next if "%CURSTR%" equ "" goto end set a=%CURSTR:~0,1% if "%a%" equ "=" (set RESULT=%RESULT%#) else (set RESULT=%RESULT%%a%) set CURSTR=%CURSTR:~1% goto next :end echo source string is %STR% echo result string is %RESULT% pause > nul
:next
是循环的入口,每次截取第一个字符,判断是 =
就在结果中拼接 #
字符,相当于完成了替换,如果字符不是 =
,就将字符直接拼接到结果中,操作之后将原串的第一个字符删除形成新的原串,然后再判断第一个字符,以此类推,直到原串为空,运行结果如下:
result string is abcdo#ocar12a#ajdjko#ot最终方案
=
,往往是替换的内容中包含 =
,上面将 =
替换成 #
不具有通用型,如果是一开始的请求,将 o=o
替换成 A
就不能这样写了,就应该是每次判断3个字符了,写起来有些麻烦,批处理中没有获得字符串长度的函数,需要自己实现一个,如果是100个字符的被替换串,那代码就很难写了。=
都能被我们替换掉,肯定有办法实现上面我们这种将 o=o
替换成 A
的要求,下面我们就列举一种通用的处理方法。0x00 首先将
=
替换成一个原串中不可能出现的字符或者序列=
替换成了 #
, 如果原串中有 #
就会弄混了,不能确定是原来字符串中就存在的 #
,还是由 =
变成的 #
。=
替换成 ###i#am#happy###
,我们把它记作 α
。0x01 用这个不能出现序列替换我们之前要查找替换子串中的
=
o=o
,那么替换之后形成 o###i#am#happy###o
,我们把它记作 β
。0x02 将第1步结束获得的替换结果作为原串,将其中的
β
替换成 A
o###i#am#happy###o
也就是原来的 o=o
替换成 A
。0x03 将第3步结果的子串作为原串,将其中的
α
替换为 =
=
,但是这个 =
不是我要替换的结果子串中的,所以要还原代码实现
@echo off rem 第一步 set CORESTR=###i#am#happy### set STR=abcdo=ocar12a=ajdjko=ot set CURSTR=%STR% set RESULT1= :next1 if "%CURSTR%" equ "" goto end1 set a=%CURSTR:~0,1% if "%a%" equ "=" (set RESULT1=%RESULT1%%CORESTR%) else (set RESULT1=%RESULT1%%a%) set CURSTR=%CURSTR:~1% goto next1 :end1 echo source1 string is %STR% echo result1 string is %RESULT1% pause > nul rem 第 2 步 set CORESTR=###i#am#happy### set STR=o=o set CURSTR=%STR% set RESULT2= :next2 if "%CURSTR%" equ "" goto end2 set a=%CURSTR:~0,1% if "%a%" equ "=" (set RESULT2=%RESULT2%%CORESTR%) else (set RESULT2=%RESULT2%%a%) set CURSTR=%CURSTR:~1% goto next2 :end2 echo source2 string is %STR% echo result2 string is %RESULT2% pause > nul rem 第3步,需要开启延迟变量 setlocal ENABLEDELAYEDEXPANSION set RESULT3=!RESULT1:%RESULT2%=A! echo result3 string is %RESULT3% pause > nul rem 第4步 set RESULT4=!RESULT3:%CORESTR%==! echo finally result is %RESULT4%
result1 string is abcdo###i#am#happy###ocar12a###i#am#happy###ajdjko###i#am#happy###ot
source2 string is o=o
result2 string is o###i#am#happy###o
result3 string is abcdAcar12a###i#am#happy###ajdjkAt
finally result is abcdAcar12a=ajdjkAto=o
被成功替换成了字母 A
,代码中用到了延迟变量,主要是为了实现被替换字符串是变量的情况,不清楚延迟变量的用法可以简单查询一下,至此文章开头提出的问题我们就成功解决了,虽然路途有些坎坷。总结
=
比较特殊,使用常规的 X:Y=Z
的语法不能替换包含 =
的子串=
替换成其他字符再进行后续操作=
的字符串,随便一个文本工具,比如记事本都可以文本进行替换sed
命令移植到 windows 的 sed.exe
程序来很方便的进行替换echo abcdo=ocar12a=ajdjko=ot | sed -e "s/o=o/A/g"
,一步就可以完成了文章开头的需求了sed.exe
程序,可以点击这个链接 sed.exe程序 下载,若不是在同一目录使用,记得将命令目录添加到环境变量中
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算