用另一个带有 shell 脚本的语句替换一个语句



我有一个语句需要替换。原始格式如下:

f.STRING.focus();

其中STRING[:alpha:][:digit:]的组合(正则表达式)。 我的目的是将其更改为

highlight("STRING");

例如:

f.abCDef12345.focus()    --->     highlight("abCDef12345");
f.ip2.focus()            --->     highlight("ip2");

我可以轻松地使用sed来替换数百个 html 文件的语句。但是,我不知道如何在 shell 脚本中获取STRING

程序可以描述如下:

For each html:
For the STRING which matches the pattern:
1. Assign it to a parameter.
2. Insert that STRING to highlight("STRING");
3. Replace the old one "f.STRING.focus();" to "highlight("STRING");"

但是我不知道如何在shell脚本中编写它们...任何提示都值得赞赏。

更新:

  1. 请清楚地描述您的脚本。太感谢了!
  2. 对不起,这个错误!STRING是 和[:alpha:][:digit:]的组合。所以这里提到的例子f.ip2.focus()是有意义的。

试试这种方法:

#!/bin/bash
while read line
do
sed 's/f.([0-9a-zA-Z]*).focus()/highlight("1")/g' $line
done < <(find . -type f  -name '*.html')

当您对输出感到满意时,将 sed-命令更改为sed -i.bak而不是执行内联替换。

解释:

  1. find命令以递归方式从当前文件夹向下搜索名为.html的所有文件
  2. bash 边读循环一次读取一行 find 命令的输出
  3. 然后sed用于搜索所需的模式,模式(...)称为标题组,它将匹配的文本存储在可以使用1访问的变量中,该变量称为反向引用。

在 bash 中读取和操作文件每一行的正确方法是使用

while read line
do
echo $line
done < file

在我们的例子中,我们没有文件,而是我们想对命令输出的每一行进行操作,输入进程替换<(...)当然,您可以使用重定向find ... > file将 find-command 重定向到文件,然后对其进行操作。

更新

正如@tripleee所指出的,while循环可以完全删除:

sed -i.bak 's/f.([0-9a-zA-Z]*).focus()/highlight("1")/g' $(find . -type f  -name '*.html')

sed '...' $(find...)构造在子 shell 中执行$()中的部分,将所有匹配的文件作为参数传递给 sed-命令,如下所示

sed '...' ./c/file.html ./a/file.html ./b/file.html ./d/file.html

如果你有很多html文件,shell可能会因为命令行太长而抛出错误;如果是这种情况,xargs是你的朋友(man xargs)。

..或者(Linux充满了TMTOWTDI),让find为所有匹配的文件执行sed部分(一次一个),这样你就不会冒着命令行太长的问题的风险:

find . -type f  -name '*.html' -exec sed 's/f.([0-9a-zA-Z]*).focus()/highlight("1")/g' {} ;
sed -i 's/f.([a-zA-Z0-9]+).focus()/highlight("1")/g' file_to_process
  1. f.比赛f.
  2. ([a-zA-Z0-9]+)匹配一个或多个字母数字字符,并将匹配的STRING存储在变量1
  3. .focus()匹配.focus()
  4. highlight("1")将整个匹配模式替换为给定的文本和变量值1->higlight("STRING")

sed -i 's/b.(STRING).focus()/highlight("1")/g' file就可以了

#echo "b.STRING.focus()"| sed 's/b.(STRING).focus()/highlight("1")/g' highlight("STRING")

您可以使用此 sed:

sed -i.bak 's/f.([[:alnum:]]+).focus()/highlight("1")/g' file.html

在这里,sed 正在发现

f.<string-with-1-and-more-alpha-numerics>.focus()

并将中间部分捕获到匹配组#1中

它正在将其替换为:

highlight("1")

其中"\1"是匹配组 #1 的反向引用

awk版本:

echo 'f.STRING.focus("Some data")' | awk '{gsub(/[[:alpha:]].[[:alpha:]]+.focus(/,"highlight(")}1'
highlight("Some data")

使用sed

echo 'b.STRING.focus("Some data")' | sed 's/[[:alpha:]].[[:alpha:]]*.focus/highlight/g'
highlight("Some data")

相关内容

  • 没有找到相关文章