文字處理的 sed 程式碼理解

文字處理的 sed 程式碼理解

誰能解釋一下下面的 sed 程式碼

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

我想編輯以添加“策略類型:”信息,當我將其替換為“策略名稱:”時,它工作正常,但是,當我添加如下所示的部分時,它顯然不起作用,因為我在不理解的情況下嘗試它。

sed -n '
/Policy Name:/! d
    s/.*:\s\+//
    h
    :1
    n
/Policy Type:/! d
    s/.*:\s\+//
    h
    :1
    n
    /Active:\s*no/d
    /HW\//!b1
    :2
    s/.*\s\(\S*\)\s*/\1/
    G
    s/\n/\t/p
    n
    /^\s*$\|Include:/! b2
    '

另外,我還有一個來自同一論壇的 AIX 等效程式碼的解決方案,我需要理解它才能編輯它以添加策略類型。

# define constants
SPC=`echo x | tr x '\040'`
TAB=`echo x | tr x '\011'`
 NL=

# custom regex for...
s="[$SPC$TAB]";   # horizontal whitespace
S="[^$SPC$TAB]";  # non-whitespace

# POSIX compliant sed code...
sed -ne "
   /Policy Name:/!d

   s/.*:$s\{1,\}//
   h

   :1
      n
      /Active:$s*no/d
   /HW\//!b1

   :2
      s/.*$s\($S*\)$s*/\1/
      G
      s/\n/$TAB/p
      n
      /^$s*\$/d
      /Include:/d
   b2
"  yourfile

輸入檔

Policy Name:       Today

  Policy Type:       Standard
  Active:              yes
  Effective date:      01/24/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  EU         NY  Cindy
                 BU         CA  Victor
                 GU         MI  Bob
  Include:
Policy Name:       Tomorrow

  Policy Type:       Oracle
  Active:              yes
  Effective date:      01/26/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  MU         LA  Martha
                 EU         CA  Sam
  Include:
Policy Name:       Yesterday

  Policy Type:       Oracle
  Active:              no
  Effective date:      01/21/2014 11:17:05
  Client Encrypt:      no
  LC/CY/Custmr:  NV         IL  Joe

  Include:`

所需輸出

Cindy    Today     Standard
Victor   Today     Standard
Bob      Today     Standard
Martha   Tomorrow  Oracle
Sam      Tomorrow  Oracle

答案1

好吧,讓我們一步一步來:

sed -n '

除非另有說明,否則該-n選項不會輸出任何內容sed

/Policy Name:/! d

所有不包含的行都Policy name:將被刪除。腳本的其餘部分僅在以下循環中處理。

s/.*:\s\+//
h

這將刪除 和 尾隨空格之前的所有內容:,並將其餘內容放入保留緩衝區中以供以後使用。

:1
n

這是讀取新行的循環的開始

/Active:\s*no/d

具有該模式的線條被刪除,因此顯然對非活動沒有興趣

/HW\//!b1

現在,我們循環判斷:1該行是否不包含HW/

:2
s/.*\s\(\S*\)\s*/\1/

下一個循環開始時,刪除除最後一個非空白序列之外的所有內容。

G
s/\n/\t/p

然後附加保存在保留緩衝區中的策略名稱,用製表符分隔並列印該行

n
/^\s*$\|Include:/! b2
'

這會在接下來的幾行中重複,直到達到給定的模式。

您應該注意,這是高度不可移植的程式碼,無法在許多sed版本上運行。

編輯:若要將策略類型新增為第三列,您應該在檢查之前或之後將此行新增至腳本Active:

/Policy Type:/{s/.*:\s*//;H;}

即:如果該行包含所述字串,則執行 之間的命令{}。這些命令刪除直到:和 尾隨空格的部分,並將該行的其餘部分(應該包含策略類型)附加到保留緩衝區。因此,保留緩衝區包含策略名稱和類型,並以換行符號分隔。因此,當我們將其附加到 時G,將會有兩個換行符號被替換,因此替換命令需要獲取標誌g來替換所有出現的情況:

s/\n/\t/gp

AIX 腳本基本上相同,但避免了對正規表示式的 GNU 擴充。主要是使用變數來匹配空格或製表符,因為它\t不適用於所有sed風格,並且+“一個或多個”需要替換為\{1,\}

相關內容