我有一个语句需要替换。原始格式如下:
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脚本中编写它们...任何提示都值得赞赏。
更新:
- 请清楚地描述您的脚本。太感谢了!
- 对不起,这个错误!
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
而不是执行内联替换。
解释:
find
命令以递归方式从当前文件夹向下搜索名为.html
的所有文件- bash 边读循环一次读取一行 find 命令的输出
- 然后
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
f.
比赛f.
([a-zA-Z0-9]+)
匹配一个或多个字母数字字符,并将匹配的STRING
存储在变量1
.focus()
匹配.focus()
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")