需要幫助掃描文本文件並查找兩個模式之間的所有單詞。就像說如果我們有一個.sql文件,需要掃描並找到'和'之間的所有單詞。 Grep一次只能掃描1行。對於這個需求,什麼是最好的Unix腳本使用? sed,awk有這些功能嗎?指出任何例子,非常感謝。Grep訪問多行,查找兩個模式之間的所有單詞
回答
桑達具有這樣的:
sed -n -e '/from/,/where/ p' file.sql
打印所有的線之間具有from
和帶where
的線行。
的東西,可以包括具有無論從哪裏線:
#!/bin/sed -nf
/from.*where/ {
s/.*\(from.*where\).*/\1/p
d
}
/from/ {
: next
N
/where/ {
s/^[^\n]*\(from.*where\)[^\n]*/\1/p
d
}
$! b next
}
這(寫爲sed腳本)稍微複雜一些,我會盡力解釋的細節。
第一行在包含from
和where
的行上執行。如果一行符合該模式,則執行兩條命令。我們使用s
替代命令僅提取from和where(包括from和where)之間的部分。該命令中的p
後綴將打印該行。 delete命令清除模式空間(工作緩衝區),加載下一行並重新啓動腳本。
當找到包含from
的行時,第二個命令開始執行一系列命令(由大括號分組)。基本上,這些命令會形成一個循環,它會將輸入中的行附加到模式空間中,直到找到包含where
的行或直到我們到達最後一行。
:
「命令」創建一個標籤,腳本中的一個標記,允許我們在需要時「跳回」。 N
命令從輸入中讀取一行,並將其追加到模式空間(用換行符分隔行)。
當找到where
時,我們可以打印出模式空間的內容,但首先我們必須使用substitute命令清理它。它與之前使用的類似,但我們現在用[^\n]*
替換前導字尾.*
,它告訴sed僅匹配非換行符,從而有效地匹配第一行中的from和最後一行中的from。然後d
命令清除模式空間並重新啓動下一行上的腳本。
b
命令將跳轉到標籤,在我們的示例中,標籤爲next
。然而,$!
地址表示它不應該在最後一行執行,讓我們離開循環。當以這種方式離開循環時,我們還沒有找到相應的where
,所以你可能不想打印它。
但是請注意,這有一些缺點。下列情況將不會按預期處理:
from ... where ... from
from ... from
where
from
where ... where
from
from
where
where
處理這些情況需要更多的代碼。
希望這有助於=)
隨着GNU awk的,所以你可以設置RS到RE:
gawk -v RS='[[:space:]]+' '
/where/ { found=0 }
found { print }
/from/ { found=1 }
' file
上述假設你不希望「從」和「在哪裏」印刷,如果有必要的話,可以移動線路來做其他事情
萬一有幫助,下面的成語描述瞭如何選擇給出 特定模式相匹配的記錄範圍:
awk '/pattern/{f=1}f' file
B):
一)從某種模式打印的所有記錄經過一番模式打印的所有記錄:
awk 'f;/pattern/{f=1}' file
c)之後,一些圖案印製的第N個記錄:
awk 'c&&!--c;/pattern/{c=N}' file
d)打印除後一些圖案中的第N個記錄中的每個記錄:
awk 'c&&!--c{next}/pattern/{c=N}1' file
E)之後的某個圖案打印的N個記錄:
awk 'c&&c--;/pattern/{c=N}' file
F)打印以外的每個記錄N記錄後的某種模式:
awk 'c&&c--{next}/pattern/{c=N}1' file
g)打印N張記錄從一些模式RDS:
awk '/pattern/{c=N}c&&c--' file
我從「F」改爲變量名的「發現」,以「C」爲「計數」,其中 適合作爲這更多表現的是什麼變量實際上是。
你可以使用ed
這個,它允許正面和負面的正則表達式的範圍。如果輸入是:
seq 10 | tee > infile
1
2
3
4
5
6
7
8
9
10
管在命令ed
:
<<< /3/,/6/p | ed -s infile
即打印包含3
和6
線之間的一切。
結果:
3
4
5
6
爲了得到每端一個多行:
<<< /3/-1,/5/+1p | ed -s infile
結果:
2
3
4
5
6
7
或者周圍的其他方式:
<<< /3/+1,/6/-1p | ed -s infile
結果:
4
5
只返回給定的兩個字符串中的一個字符串,沿awk
線(沒有得到瘋了)我只是跑這個非常平坦的腳本,冗長拖:
.\gnucoreutils\bin\awk "{startstring = \"RETURN STUFF AFTER ME \"; endstring = \"RETURN STUFF BEFORE ME\"; endofstartstring = index($0,startstring)+length(startstring); print substr($0,endofstartstring,index($0,endstring)-endofstartstring)}" /dev/stdin
請注意,我用的cmd.exe
(在Windows命令解釋器)和the gnuwin32 awk,那麼介意「雙引號」和^ \轉義字符^ \:
GNU Awk 3.1.6
Copyright (C) 1989, 1991-2007 Free Software Foundation.
請指出缺點。
例如:
echo "hello. RETURN STUFF AFTER ME i get returned RETURN STUFF BEFORE ME my face is melting" | .\gnucoreutils\bin\awk "{startstring = \"RETURN STUFF AFTER ME \"; endstring = \" RETURN STUFF BEFORE ME\"; endofstartstring = index($0,startstring)+length(startstring); print substr($0,endofstartstring,index($0,endstring)-endofstartstring)}" /dev/stdin
i get returned
我能做到這一點只用grep的:
#> grep -A#### "start pattern" file | grep -B#### "end pattern"
的問題是,我必須找到線適量的A和B,包括選項,這是相同的。 希望這可以幫助
- 1. 用於查找兩個單詞之間的所有數據的模式
- 2. 查找兩個單詞之間的相鄰單詞列表
- 3. 使用grep查找兩個大型單詞列表之間的差異
- 4. 獲取所有兩個特定單詞之間的詞在python
- 5. 在正則表達式中查找兩個單詞之間的詞
- 6. 查找全文中的%和%之間的所有單詞?
- 7. 如何grep Perl中兩個符號之間的單詞?
- 8. SQL查找兩個相同模式表之間的匹配行
- 9. 如何查找括號之間出現的所有單詞?
- 10. 查找和替換POM中兩個單詞之間的內容
- 11. 選擇兩個單詞之間的詞
- 12. 從文件中提取兩個模式之間的所有行
- 13. 正則表達式模式獲取兩個單詞之間的所有行文本
- 14. Python - 剪切兩個字符串之間的所有單詞
- 15. REGEX捕獲兩個字符串之間的所有單詞
- 16. 提取兩個文本之間改變的所有單詞PHP
- 17. 提取字符向量中兩個特定單詞之間的所有單詞
- 18. PHP得到所有可能的行(兩個詞之間)
- 19. 查找具有「grep」的特定單詞的行號
- 20. 如果兩個單詞之間存在一個單詞,如何刪除它們之間的所有內容?
- 21. 兩個單詞之間的正則表達式 - 或行尾?
- 22. 使用grep查找有兩個's'的空格分隔的單詞
- 23. Java表達式查找多個單詞
- 24. 使用模式的兩個文件之間的grep
- 25. 查找包含列表中兩個或更多單詞的行
- 26. 正則表達式:找到兩個詞之間的空間
- 27. libgit2:查找兩個標籤之間的所有提交?
- 28. 查找兩個節點之間的所有路徑
- 29. 查找兩個頂點(節點)之間的所有路徑
- 30. 使用BFS查找兩個節點之間的所有路徑
你能粘貼一個示例sql內容嗎?例如有多少來自...你文件中的哪個位置?有沒有在同一行中「from」和「where」的情況?所有這些使得提取邏輯不同。 – Kent
這個答案也可能適用:https://stackoverflow.com/a/48022994/2026975 – imriss