仅替换正则表达式匹配中的字符



我试图在文本文件中搜索正则表达式,而不是在匹配范围内只用另一个字符替换一个字符。我的问题是,我无法通过某种简单的方式做到这一点。

示例源文件:

...
 <br>
<a id="some shopitem" ref="#some shop item name 01 a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a>
<table>
 <td width="500">
....

在那里我需要匹配正则表达式ref="#[[:alnum:] ]*"(ref="#whatever 名称与空格"),并将空格替换为"-",但当然不要更改另一个空格或正则表达式匹配。

所以结果应该看起来像这样:

....
 <br>
<a id="some shopitem" href="#some-shop-item-name-01-a" style="text-decoration:none;"><h3 style="background-color: #ccc;">blah blab hasdk sldk sasdas dasda sd</h3></a>
<table>
 <td width="500">
....

甚至有可能在没有某种脚本的情况下仅在 bash 中的一行命令中做到这一点吗?有没有办法替换组中的空间?像sed -r s/ref="#([[:alnum:] ]*)/(1s/ /-/g)/g'

一个perl解决方案:

perl -pe 's/(ref="#)([ws]+)(")/ ($x,$y,$z)=($1,$2,$3); $y =~ s{s}{-}g; $x.$y.$z /eg'

它对引用名称中可以出现的内容稍微宽松一些(下划线、制表符、其他一些空格字符)

甚至有可能在没有某种脚本的情况下仅在 bash 中的一行命令中做到这一点吗?

你的问题不知何故引发了我这样做的强烈野心......!

varfile=SOURCEFILE && varsubstfile=RESULTFILE && IFS=' ' read -a repl <<< $(sed -r 's/(.*)(ref="#.*?")( .*)/2/;tx;d;:x' $varfile | sed -e 's/ /-/g' | sed ':a;N;$!ba;s/s/ /g') && for i in "${!repl[@]}"; do needle["$i"]=$(sed 's/-/ /g' <<< "${repl["$i"]}"); done && cp $varfile $varsubstfile && for i in "${!needle[@]}"; do sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; done && unset needle && unset repl && less $varsubstfile && unset varfile && unset varsubstfile

SOURCEFILE是源文件,RESULTFILE是写入输出的文件的名称,因此请根据需要更改它们。

井。。。这是一种脚本,但它是一个(该死的巨大)单行:)

我认为整个文件中出现ref="#.*"次数更多,否则它会短得多(尽管我不记得较短的版本了)。

。我真的希望这适用于您的 *nix 系统:D


以防万一你想知道这个东西是做什么的,这里有一个解释:
varfile=SOURCEFILE && #set variable for the sourcefile
varsubstfile=RESULTFILE && #set variable for the resultfile
IFS=' ' read -a repl <<< #we're going to read multiple values into an array "repl"
                         #delimited by a space
   $(
     #grab only the second capture group (ref="#.*?")
     sed -r 's/(.*)(ref="#.*?")( .*)/2/;tx;d;:x' $varfile |
     sed -e 's/ /-/g' | #replace every space in (ref="#.*?") with a dash
     sed ':a;N;$!ba;s/s/ /g' #replace newlines with a space
     #when there is more than one occurence sed will delimit them with a newline
     #but i set a space as the delimiter for the read operation,
     #thus the last replacement
   ) &&
#we now have every needed replacement-string in an array called "repl"
for i in "${!repl[@]}"; do #iterate over every value in the array we just read
  needle["$i"]=$(sed 's/-/ /g' <<< "${repl["$i"]}"); #replace dashes with spaces and store in a new variable
done &&
#and now every original string, the needle we are going to search for
#is stored in another array
cp $varfile $varsubstfile && #copy sourcefile to resultfile
for i in "${!needle[@]}"; do #for every string we are going to replace
  sed -ir "s/${needle[i]}/${repl[i]}/g" $varsubstfile; #... we replace it!
done
#technically we're done here
#but i like to clean up afterwards and show the result with less
unset repl && less $varsubstfile && unset varfile && unset varsubstfile

相关内容

  • 没有找到相关文章

最新更新