繁体   English   中英

这个shell / sed脚本怎么了?

[英]What's wrong with this shell/sed script?

我要对给定目录中的大约150个HTML文件进行一些更改。 一些锚标记具有沿以下几行的href: index.php?page=something 我希望将所有这些都更改为something.html 简单的正则表达式,简单的脚本。 不过,我似乎无法正确理解。 有人可以对我做错了吗?

输出之前和之后的示例html:

<!-- Before -->
<ul>
    <li><a href="#">Apple</a></li>
    <li><a href="index.php?page=dandelion">Dandelion</a></li>
    <li><a href="index.php?page=elephant">Elephant</a></li>
    <li><a href="index.php?page=resonate">Resonate</a></li>
</ul>

<!-- After -->
<ul>
    <li><a href="#">Apple</a></li>
    <li><a href="dandelion.html">Dandelion</a></li>
    <li><a href="elephant.html">Elephant</a></li>
    <li><a href="resonate.html">Resonate</a></li>
</ul>

脚本文件:

#! /bin/bash

for f in *.html
do
    sed s/\"index\.php?page=\([.]*\)\"/\1\.html/g < $f >! $f
done

这是您的正则表达式,并且外壳程序正在尝试解释您的正则表达式的事实。

首先- [.]*匹配任意数量的文字点. 将其更改为.*

其次,包围整个正则表达式中的单引号' ,以防止在bash shell解释它的任何。

sed 's/"index\.php?page=\(.*\)"/\1\.html/g'

另外,代替< $f >! $f < $f >! $f您只需将'-i'开关输入sed即可使其就地运行:

sed -i 's/"index\.php?page=\(.*\)"/"\1\.html"/g' "$f"

(另外,我想在替换中,您需要在\\1.html周围用双引号引起来,以便在HTML \\1.html新的引号引起来。我还将$f引用为"$f" ,因为如果文件名包含空格bash会抱怨)。

编辑 :正如@TimPote所指出的,在引号内匹配内容的标准方法是".*?" (因此.*是非贪婪的)或"[^"]+" 。Sed不支持前者,因此请尝试:

sed -i 's/"index\.php?page=\([^"]\+\)"/"\1\.html"/g' "$f"

这是为了防止(例如) <a href="index.php?page=asdf">"asdf"</a>变成<a href="asdf">"asdf.html"</a> (其中(.*)捕获asdf">"asdf表示贪婪)。

您的.*太贪婪。 使用[^"]\\+代替。加上您的引号都被弄乱了。整个内容都用单引号引起来,然后您可以使用"而不必转义。

sed -i 's/"index\.php?page=\([^"]\+\)"/"\1\.html"/g'

您可以使用find使用单个语句完成整个操作:

find . -maxdepth 1 -type f -name '*.html' \
 -exec sed -i 's/"index\.php?page=\([^"]\+\)"/"\1\.html"/g' {} \+

以下作品:

 sed "s/\"index\.php?page=\(.*\)\"/\"\1.html\"/g" < 1.html 

我认为主要是方括号。 不知道为什么要拥有它们。 哦,整个sed命令需要用引号引起来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM