问题是*
一个贪婪的运算符,所以它会尽可能多地匹配,导致它不是在第一个可能的匹配上停止,而是在最后一个可能的匹配上停止。因此,您可能应该更改它尝试匹配的内容。问题是您希望它匹配除另一个“downloadsubtitle.php?id=”之外的任何内容,这在sed
. 您可以创建一个更复杂的 sed 脚本,也可以使用一个简单的解决方法,假设?
链接和标题之间没有任何 s =)
sed -nr 's/.*downloadsubtitle.php\?id\=([0-9]+)[^?]*hebrew[^?]*DESPiTE.*/\1/p'
如果你想要一个合适的脚本:
#!/bin/sed -nf
: next
$! { N; b next }
s/\n//g
s/downloadsubtitle\.php?id=\([0-9][0-9]*\)/\
\1/
: loop
s/^[^\n]*\n//
h
s/\([0-9]*\).*/\1/
x
s/downloadsubtitle\.php?id=\([0-9][0-9]*\)/\
\1/
/^[^\n]*hebrew[^\n]*DESPiTE/ { g; p; q }
/^[0-9]*/ b loop
该脚本首先将整个文件加载到模式空间(即工作缓冲区)中。它在前两行中执行此操作。第一行声明了一个next
用:
“命令”调用的标签。第二行使用命令将输入的下一行附加到模式空间中N
,然后跳回next
标签,但这两个命令只有在我们还没有读到最后一行的情况下才会执行。第三行删除所有换行符。
现在,我们将第一次出现的 替换downloadsubtitle\.php?id=[0-9][0-9]*
为换行符(由反斜杠后跟一个实际的换行符表示)和 ID 号。
创建了一个新标签loop
,我们在它之后做的第一件事就是删除第一个换行符之前的所有内容(因此我们删除了 id 之前的所有内容)。
现在我们有一系列命令可以提取数字并将其存储到保持空间(辅助缓冲区)中。我们首先使用命令将整个模式空间复制到保持空间中h
,然后删除数字后面的所有内容,然后将保持和模式空间的内容与x
. 现在保持空间包含数字,并且模式空间恢复到它的值。
为了防止贪婪搜索,我们将在下一次出现之前放置一个换行符downloadsubtitle\.php?id=[0-9][0-9]*
。我们也可以只留下 ID 号,因为换行符将表明我们找到了字符串的其余部分。
现在是搜索部分。回顾一下,我们在保持空间中有实际的 ID,模式空间的第一行是我们要搜索文本的地方。因此,我们使用搜索表达式,从缓冲区的开头开始搜索字符串hebrew
,DESPiTE
并且这些字符串没有相互分隔,也没有从缓冲区的开头用换行符分隔。因此,我们只搜索了第一行。
如果找到匹配项,我们使用g
从保留空间中获取 ID,p
打印它,然后q
退出。
如果我们没有找到匹配项,我们只需跳回loop
标签,并搜索下一个出现。跳转前的条件是防止死循环。如果没有什么可搜索的,它就会退出。
希望这会有所帮助=)