我有一个大型的文档网站,如下所示:<title>DOCTITLE</title>
<h1>Some Title</h1>
我正在尝试使用Cygwin在每个文件中用Some Title替换DOCTITLE。
更具体地说,我需要从每个文件中提取<h1>
标记之间的任何文本,并用提取的文本替换文本字符串"DOCTITLE"。
这里有一个想法不起作用,但它说明了我追求的精神:
find . -name "*html"
-exec sed -i
's/DOCTITLE/'$(grep "h1" | sed 's/<h1>(.*)</h1>/1/')'/'
'{}' /;
不出所料,这会失败,因为grep没有输入,它会破坏<h1>
。
有什么想法吗?
感谢您的时间和专业知识!
您的方法——使用$( … )
——不会起作用,因为sed
的-exec
参数无法处理该语法。然而,我们可以做的是调用bash
为我们做这项工作:
find . -name '*.html' -exec /bin/bash -c 'sed "s/DOCTITLE/$(sed -n ''',<h1>.*</h1>,{s,<h1>(.*)</h1>,1,p;q}''' '''{}''')/" "{}"' ;
外部sed
的作用与sed
命令的作用完全相同。内部$( … )
部分由bash
扩展,只生成第一个<h1>
之间的文本(如果不需要只获得第一个匹配,则会简单得多)。
具体来说,内部sed
默认不打印任何内容(-n
),然后对于与正则表达式<h1>.*</h1>
匹配的行,它运行s,<h1>(.*)</h1>,1,p;q
,即剥离HTML标签,打印结果,然后退出;CCD_ 18确保我们只打印出第一个匹配项。
注意,我使用sed -n
避免了使用grep
;您可以用下面的命令做同样的事情,-m
选项到grep
将命令限制为第一个匹配。
find . -name '*.html' -exec /bin/bash -c 'sed "s/DOCTITLE/$(grep -m1 '''<h1>.*</h1>''' '''{}''' | sed '''s,<h1>(.*)</h1>,1,''')/" "{}"' ;
在这两种情况下,都有一些稍微可怕的引用:'''
序列将一个引用插入到一个引用字符串中。我们需要引用sed
语句,以确保标题中的任何空格都不会引起问题,并且我们需要引用文件名,以便能够处理文件名中的空格。
这可能对你有用(GNU sed):
find . -name "*html" -exec sed -i '$!N;s/DOCTITLE([^n]*n<h1>([^<]*)</h1>)/21/;P;D' {};
这需要首先进行广泛的测试!