删除不需要的文本

删除不需要的文本

我的桌面上有一个很大的 html 文件,看起来像

src="http://images.alaablubnan.com/images/Balls/20.jpg"
alt="http://images.alaablubnan.com/images/Balls/20.jpg"/></a></td><td><a
href="http://images.alaablubnan.com/images/Balls/32.jpg"
target="_blank"><img
src="http://images.alaablubnan.com/images/Balls/32.jpg"
alt="http://images.alaablubnan.com/images/Balls/32.jpg"/></a></td><td><a
href="http://images.alaablubnan.com/images/Balls/30.jpg"
target="_blank"><img
src="http://images.alaablubnan.com/images/Balls/30.jpg"
alt="http://images.alaablubnan.com/images/Balls/30.jpg"/></a></td></tr><tr><td><table><tr><td>webpage/url</td><td>http://www.playlebanon.com/webservices/website/lotto/PopUps/HistoryDetail.aspx?t=1405536730503&FromDraw=1&ToDraw=1213&Draw=0</td></tr></table></td><td>2</td><td>complete
lotto results</td><td>complete lotto results</td><td>2</td><td><a
href="http://www.playlebanon.com/webservices/website/lotto/PopUps/HistoryDetail.

如果可能的话,我想:

  • 获取所有 .jpg 文件,删除所有 html 代码(包括 1.jpg、2.jpg... 到 42.jpg)
  • 我想删除 .jpg 扩展名
  • 我希望每行数字只有 7 个数字,然后插入新行

答案1

这实际上并不是一份特别好的工作,sed但情况如下:

sed -nr 's#.*/([^"]+).jpg.*#\1#p' file 

以上将为您提供一个数字列表,每行一个:

20
20
32
32
32
30
30
30

现在,实际上可以将所有这些放在同一行,每行 7 个数字,sed但这真的不值得付出努力。只需使用标准 *nix 工具即可:

$ echo $(sed -nr 's#.*/([^"]+).jpg.*#\1#p' file | tr $'\n' ' ') | fold -sw 21
20 20 32 32 32 30 30 
30

或者,如果您想删除重复项:

echo $(sed -nr 's#.*/([^"]+).jpg.*#\1#p' file | sort -u | tr $'\n' ' ')
20 30 32

解释

sed命令使用了一些技巧:

  • -n:默认情况下不打印任何行。
  • -r:启用扩展正则表达式,这让我们可以( )使用捕获组而不需要转义括号和+“一个或多个”。
  • s#from#to#sed: 虽然和其他类似工具中的标准替换运算符是s/from/to/,但您可以使用非标准分隔符,以便将其包含/在模式中。在本例中,我使用的是#但您也可以使用其他类似的东西s|from|to|
  • s#.*/([^"]+).jpg.*#\1#p:这将匹配从行首到 a 的所有内容/,然后捕获最长的非 字符,"直到.jpg。这是文件名减去扩展名。文件名在括号中捕获,整行(因为.*两边都有 )将替换为捕获的模式(\1)。p末尾的 表示它将打印替换成功的行。

perl但就我个人而言,我首先会这样做:

$ perl -e '@k=grep(s/.*\/([^"]+).jpg.*/$1/s,<>); print "@k[0..6]\n@k[7..$#k]\n"' file 
20 20 32 32 32 30 30
30

或者,对于较大的文件:

$ perl -e '@k=grep(s/.*\/([^"]+).jpg.*/$1/s,<>); for($i=0;$i<=$#k;$i+=7){print "@k[$i..$i+7]\n"}' file 
20 20 32 32 32 30 30 30
30       

甚至grep

$ echo $(grep -oP '[^/]+(?=.jpg)' file | tr $'\n' ' ' ) | fold -w 21
20 20 32 32 32 30 30 
30

或者,窃取@Olli 的聪明xargs想法:

$ grep -oP '[^/]+(?=.jpg)' file |  xargs -n7 echo
20 20 32 32 32 30 30
30

答案2

我假设您试图抓取某种结果。在这个例子中,只有三个球,我们可以通过搜索Balls/<one-or-many-digits>并围绕数字分组(构造\(..\))然后用该组替换所有球(是\1对第一个组的引用)来提取它们。

$ sed -n 's/.*Balls\/\([0-9]\+\).*/\1/gp' htmlfile | uniq | xargs -n7 echo
20 32 30

sed逐行检查。我要求它匹配并替换行上的所有内容(这就是为什么我们在每个末尾都加上.*“任意数量”的原因),将其替换为组中匹配的内容。 和-n一起/p使用表示除非该行匹配,否则不打印, 表示/g它会一直匹配,直到到达文件末尾。

如果您不熟悉正则表达式,这是一个相当复杂的例子。

我将其传递过去,uniq因为那里有很多重复。

| xargs -n7 echo在末尾使用将 7 个参数组合在一起并将它们全部传递给echo。这里没有 7 个球,所以只显示 3 个。


-r它可能会减慢速度,但如果使用扩展语法,则可以获得更易读的表达式sed

sed -nr 's/.*Balls\/([0-9]+).*/\1/gp' htmlfile | ...

做同样的事情,只是没有一些看起来令人困惑的转义。
可能稍微慢一点。

相关内容