Shell
使用 AWK 提取以 *** 分隔的段落
我有一個如下文件:
blablabla blablabla *** thingsIwantToRead1 thingsIwantToRead2 thingsIwantToRead3 blablabla blablabla
我想用
thingsIwantToRead
. 當我不得不處理這樣的問題時,我像這樣使用 A WK:awk 'BEGIN{ FS="Separator above the paragraph"; RS="" } {print $2}' $file.txt | awk 'BEGIN{ FS="separator below the paragraph"; RS="" } {print $1}'
它奏效了。
在這種情況下,我嘗試輸入
FS="***"
,"\*{3}"
,"\*\*"
(它不起作用,因為 AWK 將它視為普通星號),"\\*\\*"
或者我能想到的任何正則表達式,但它不起作用(它什麼也沒列印)。你知道為什麼嗎?
如果沒有,你知道另一種方法來處理我的問題嗎?
下面是我要解析的文件的摘錄:
13.2000000000 , 3*0.00000000000 , 11.6500000000 , 3*0.00000000000 , 17.8800000000 Blablabla SATELLITE EPHEMERIS =================== Output frame: Mean of J2000 Epoch A E I RA AofP TA Flight Ang ***************************************************************************************************************** 2012/10/01 00:00:00.000 6998.239 0.001233 97.95558 77.41733 89.98551 290.75808 359.93398 2012/10/01 00:05:00.000 6993.163 0.001168 97.95869 77.41920 124.72698 274.57362 359.93327 2012/10/01 00:10:00.000 6987.347 0.001004 97.96219 77.42327 170.94020 246.92395 359.94706 2012/10/01 00:15:00.000 6983.173 0.000893 97.96468 77.42930 224.76158 211.67042 359.97311 <np> ---------------- Predicted Orbit: ---------------- Blablabla
我想提取:
2012/10/01 00:00:00.000 6998.239 0.001233 97.95558 77.41733 89.98551 290.75808 359.93398 2012/10/01 00:05:00.000 6993.163 0.001168 97.95869 77.41920 124.72698 274.57362 359.93327 2012/10/01 00:10:00.000 6987.347 0.001004 97.96219 77.42327 170.94020 246.92395 359.94706 2012/10/01 00:15:00.000 6983.173 0.000893 97.96468 77.42930 224.76158 211.67042 359.97311
我試圖用來獲取 * 行之後的數字的命令:
`awk 'BEGIN{ FS="\\*{2,}"; RS="" } {print $2}' file | awk 'BEGIN{ FS="<np>"; RS="" } {print $1}'`
告訴 awk 在兩個分隔符之間列印。具體來說:
awk '/\*{4,}/,/<np>/' file
這還將列印包含分隔符的行,因此您可以使用以下命令刪除它們:
awk '/\*{4,}/,/<np>/' file | tail -n +2 | head -n -1
或者,如果一行與第一個分隔符匹配,您可以將變數設置為 true,當它與第二個分隔符匹配時設置為 false,並且僅在為 true 時列印:
awk '/\*{4,}/{a=1; next}/<np>/{a=0}(a==1){print}' file
a
如果目前行匹配 4 個或更多,則上面的命令將設置為 1,*
並且也會跳到該next
行。這意味著該***
行將永遠不會被列印。這是對原始的,被誤解的問題版本的回答。我把它留在這裡,因為它在稍微不同的情況下很有用。
首先,你不想要
FS
(欄位分隔符),你想要RS
(記錄分隔符)。然後,要傳遞文字*
,您需要對其進行兩次轉義。一次轉義,一次轉義反斜杠(否則,awk 將嘗試以與or*
相同的方式匹配它)。然後,列印第二個“行”:\r``\t
$ awk -vRS='\\*\\*\\*' 'NR==2' file thingsIwantToRead1 thingsIwantToRead2 thingsIwantToRead3
要避免輸出周圍出現空行,請使用:
$ awk -vRS='\n\\*\\*\\*\n' 'NR==2' file thingsIwantToRead1 thingsIwantToRead2 thingsIwantToRead3
請注意,這假設
***
在每個段落之後都有一個,而不僅僅是在您顯示的第一個段落之後。