用shell脚本替换另一个语句

时间:2014-02-14 11:53:20

标签: regex bash shell sed

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

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()是有道理的。

5 个答案:

答案 0 :(得分:2)

尝试这种方法:

#!/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-command更改为sed -i.bak,而不是进行内联替换。

说明:

  1. find命令从当前文件夹中递归搜索,向下搜索名为.html的所有文件
  2. bash while-read循环一次读取find-command
  3. 输出的一行
  4. sed用于搜索所需的模式,模式\(...\)称为标题组,用于将匹配的文本存储在可使用\1访问的变量中。称为反向引用。
  5. 使用正确方式在bash中读取和操作文件的每一行是

    while read line
    do
        echo $line
    done < file
    

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

    <强>更新

    正如@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是你的朋友(男人xargs)。

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

    find . -type f  -name '*.html' -exec sed 's/f\.\([0-9a-zA-Z]*\)\.focus()/highlight("\1")/g' {} \;
    

答案 1 :(得分:2)

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的值替换整个匹配的模式 - &gt; higlight("STRING")

答案 2 :(得分:0)

sed -i 's/b.\(STRING\).focus()/highlight("\1")/g' file会做到这一点

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

答案 3 :(得分:0)

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")

答案 4 :(得分:0)

您可以使用此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的反向引用