我有一些 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
这同样适用。)perl
sed
使用您的特定命令后结果如下所示:
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
进一步阅读: