問題是*
是一個貪婪的運算符,所以它會盡可能地匹配,導致它不會停止在第一個可能的匹配上,而是在最後一次可能的匹配上停止。因此,你應該改變它試圖匹配的內容。問題是你希望它匹配除了另一個「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
標籤,但只有在我們還沒有讀取最後一行時纔會執行這兩個命令。第三行刪除所有換行符。
現在,我們用一個換行符(用反斜線後跟一個實際的新行代表)和ID號替換第一個出現downloadsubtitle\.php?id=[0-9][0-9]*
。
創建了一個新的標籤loop
,我們在做之後的第一件事是刪除第一個換行符(因此我們刪除了id之前的所有內容)。
現在我們有一系列命令將提取數字並將其存儲到保留空間(輔助緩衝區)中。我們首先使用h
命令將整個圖案空間複製到保持空間中,然後刪除數字後的所有內容,然後將保持和圖案空間的內容與x
交換。現在保持空間包含數字,模式空間已恢復爲其值。
爲了防止貪婪搜索,我們會在下一個出現downloadsubtitle\.php?id=[0-9][0-9]*
之前放置一個換行符。我們也可以只留下身份證號碼,因爲換行符會指示我們找到了字符串的其餘部分。
現在來搜索部分。總而言之,我們在保持空間中有實際的ID,並且模式空間的第一行是我們想要搜索文本的位置。因此,我們使用搜索表達式從緩衝區起始處搜索字符串hebrew
和DESPiTE
,並且這些字符串不是彼此分開的,也不是從緩衝區的起始位置用換行符分隔的。因此,我們只搜索第一行。
如果找到匹配項,我們使用g
從保存空間中獲取ID,p
打印它,然後q
退出。
如果我們找不到匹配項,我們只需跳回loop
標籤,然後搜索下一個發生位置。跳轉之前的條件是爲了防止無限循環。如果沒有什麼可搜索的,它就會退出。
希望這有助於=)
potong - 您的解決方案就像一個魅力!謝謝 – buntuser