为什么 sed 不工作?

为什么 sed 不工作?

我有一些 HTML,想从中提取链接。目前文件如下所示。

website.com/path/to/file/234432517.gif" width="620">
website.com/path/to/file/143743e53.gif" width="620">
website.com/path/to/file/123473232.gif" width="620">
website.com/path/to/file/634132317.gif" width="620">
website.com/path/to/file/432432173.gif" width="620">

" width="620">我正在尝试使用 sed从所有行中删除。这是我的 sed 代码:

sudo sed -i "s/\"\swidth\=\"\d+\"\>//g" output

为什么这不起作用?我用谷歌搜索的所有内容都指向一些看起来像这样的代码,但由于某种原因,这不起作用。

答案1

因为您使用的是 PCRE(Perl 兼容正则表达式)语法,但sed并不理解这一点,所以它默认使用基本正则表达式 (BRE)。它既不知道\s也不知道\d。您还会转义各种不需要转义的内容( 和\=\>没有做任何有用的事情),而不会转义需要转义的内容(+只是表示 BRE 中的符号+,您需要\+“一个或多个”。

这应该可以满足您的需要:

sed 's/" width="[0-9]\+">//g' file

或者,使用扩展正则表达式:

sed -E 's/"\s*width="[0-9]+">//g' file

最后,一般来说,你绝不sed -i在没有先测试的情况下使用-i以确保它有效,或者,如果你这样做,至少使用-i.bak-i任何文本都可以这样做)来创建备份。

答案2

以下是我的sed解决方案:

sed -E 's/(.*)" width="[0-9]+">/\1/' filename

作为替代方法,sed我建议使用grep从文件中提取数据:

这对你有用:

grep -o "website.*\.gif" filename

正如 terdon 所建议的,这里有一个使用前瞻解决方案grep

grep -Po '.*(?="\swidth="\d*">)' filename

在你的情况下也是cut一个不错的选择:

cut -f1 -d'"' filename

答案3

或者,为了缩短交流时间,只需删除所有内容即可gif

sed 's/gif.*/gif/' file

匹配.*任意数量的任意字符,只要您想要丢失的内容始终位于您可以找到的字符串之后...并且一行中没有其他实例。它会匹配website.com/path/to/gif/xyz.gif" width..."较早的gif,因此会产生不理想的结果。

答案4

因为你写了一个Perl 正则表达式,你可以使用 Perl。您可以发出一行perl命令而不是sed命令。那么您就不必将正则表达式翻译成不同的方言,也不必放弃 Perl 的任何便捷功能。

  • 而要sed -i使用perl -pi -e
  • sed -i.bak不要使用 ,而要使用perl -pi.bak -e。(您可以使用任何后缀,不必是.bak。)

作为特登说-i最好指定一个后缀,这样它就会创建一个备份文件,至少如果你还没有尝试过没有先执行相同的命令的话。(对于和 对于 来说,-i这同样适用。)perlsed

使用您的特定命令后结果如下所示:

perl -pi.bak -e "s/\"\swidth\=\"\d+\"\>//g" file

如果你使用单引号围绕搜索和替换模式,你不必转义"其中出现的字符,也不必跟踪 shell 的有趣的规则对于双引号文本。这将使书写和阅读更加容易。(这并非特定于perl;您的sed命令可以同样简化。)此命令等效于:

perl -pi.bak -e 's/"\swidth\="\d+"\>//g' file

使用其中任何一个命令,示例中的行都会更改为:

website.com/path/to/file/234432517.gif
website.com/path/to/file/143743e53.gif
website.com/path/to/file/123473232.gif
website.com/path/to/file/634132317.gif
website.com/path/to/file/432432173.gif

进一步阅读:

相关内容