Shell

使用 AWK 提取以 *** 分隔的段落

  • June 10, 2015

我有一個如下文件:

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  

請注意,這假設***每個段落之後都有一個,而不僅僅是在您顯示的第一個段落之後。

引用自:https://unix.stackexchange.com/questions/208667