2013-11-27 21 views
3

我在阅读页面并试图从中提取一些数据。我对使用bash感兴趣,并且在经历了几个链接之后,我才知道'Shell参数扩展'可能会有所帮助,但我发现在我的脚本中使用它非常困难。我知道使用sed可能会更容易,但就我的知识而言,我想知道如何在bash中实现此目标。在Shell参数扩展中使用模式

shopt -s extglob 

str='My work</u><br /><span style="color: rgb(34,34,34);"></span><span>abc-X7-27ABC | </span><span style="color: rgb(34,34,34);">build' 
echo "${str//<.*>/|}" 

我希望我的输出是这样的:My work|abc-X7-27ABC |build

我想检查是否接受,而不是模式只字,它似乎用言语来工作的。

例如,
echo "${str//span style/|}"的作品,但
echo "${str//span.*style/|}"

在另一方面,我的链接,它接受模式的人看到。我很困惑,为什么它不适用于我上面使用的模板。

How to make sed do non-greedy match? (用户konsolebox的解决方案)

+0

你保证有一个'|在'ABC ...''部分字符? – devnull

+0

|角色最初不会在那里。你可以忽略它。我想要的是删除_before_和_ after_下面的所有内容:_My work_,_abc-X7-27ABC_和_build_。当我删除HTML语法时,我想要| |作为替代人物。因此,输出应该像'我的工作| abc-X7-27ABC | build' – Technext

回答

3

一个你正在做的错误是由混合壳通配和正则表达式。在shell glob点字面上被认为是点字符而不是任何字符的0或更多。

如果你试试这个代码,而不是:

echo "${str//<*>/|}" 

那么它会打印:

My work|build 
+0

谢谢@anubhava的指示。现在的问题是,我没有得到我真正想要的结果。它正在进行一场贪婪的比赛。有什么办法可以使用'$ {parameter%word}'这样的东西来获得我想在bash中输出的结果:'我的工作| abc-X7-27ABC | build'? – Technext

+0

@Technext:我目前在手机上。当我回到我的电脑时,我会玩你的输入文字,看看我能否得到想要的输出。 – anubhava

+3

这里的问题是,你不想要一个贪婪的比赛在这里(其中吃掉一切从''标签到''“建设”之前),但你也不想一个非贪婪匹配(这会导致过多的换人:“我的工作||||| ABC-X7-27ABC | ||建”,对正则表达式和HTML解析推移(同样的忠告“不要用一个适当的HTML解析器。 。“)适用更是如此外壳的图案,这是不太强大,主要用于匹配简单集的文件名的 – chepner

1

这不是一个答案,这么多的为什么不推荐模式匹配的演示这种HTML编辑。我尝试了以下。

shopt -s extglob 
set +H # Turn off history expansion, if necessary, to allow the !(...) pattern 
echo ${str//+(<+(!(>))>)/|} 

第一:它没有工作,即使是像str='My work</u><br />bob<foo>build'这样简单的字符串。其次,对于原始问题中的字符串,它似乎锁定了外壳;我怀疑这种复杂的模式会触发指数回溯。

下面是它是如何打算工作:

  1. !(>)比单个>
  2. +(!(>))以外的任何东西是一个或多个非>字符。
  3. <+(!(>))>是一个或多个非>字符括在<>
  4. +(<+(!(>))>)<...> -enclosed非>■一个或多个组。

我的理论是,既然!(>)可以匹配多字符串以及单个字符,有需要回溯的