awkコマンドをawkスクリプトに変換(マルチF)

awkコマンドをawkスクリプトに変換(マルチF)

作業コマンドがあります

awk  -F '[)#/(:]' 'BEGIN  { fw="";dev=""} {if ($0~/sh failover/) fw=$1 ; if (($0~/This host/)||($0~/Other host/)) dev=$2; if ($0~/\)\:/) {print $2,$1,fw, dev} }' OFS="|" test_data

これをスクリプトにしたいです。これをするとき...

#!/bin/sh
awk '
BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} 
{
    if ($0~/sh failover/) fw=$1 ; 
    if (($0~/This host/)||($0~/Other host/)) dev=$2; 
    if ($0~/\)\:/) {
        print $2,$1,fw, dev
        } 
}' test_data 

...F='[)#/(:]' エラーが発生します。

[...srv01]$ ./test
./test: line 3: syntax error near unexpected token `)'
./test: line 3: `BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} '
[...srv01]$ 

二重引用符に変更すると、二重引用符間のすべての内容が区切り文字で表示されるので、代わりに )#/(: を検索します。)または#または/またはまたは:

test_dataのファイル内容です。

[...srv01]$ cat test_data
JoeASA# sh failover | i \)\:|host
        This host: Primary - Active
                  admin Interface management (313.13.0.13): Normal (Monitored)
                  DMZ-FW Interface Inside (310.13.19.7): Normal (Not-Monitored)
                  DMZ-FW Interface Outside-Zone2 (912.168.119.7): Normal (Not-Monitored)
                  ENET Interface OUTSIDE(912.168.191.7): Normal (Not-Monitored)
                  ENET Interface dmarc (912.168.192.7): Normal (Not-Monitored)
                  GW Interface Extranet (912.168.23.27): Normal (Not-Monitored)
                  GW Interface Outside-Zone (912.168.123.27): Normal (Not-Monitored)
                  GW Interface management (331.1.1.47): Normal (Not-Monitored)
        Other host: Secondary - Standby Ready
                  admin Interface management (313.13.0.12): Normal (Monitored)
                  DMZ-FW Interface Inside (310.13.19.6): Normal (Not-Monitored)
                  DMZ-FW Interface Outside-Zone2 (912.168.119.6): Normal (Not-Monitored)
                  ENET Interface OUTSIDE(912.168.191.6): Normal (Not-Monitored)
                  ENET Interface dmarc (912.168.192.6): Normal (Not-Monitored)
                  GW Interface Extranet (912.168.23.26): Normal (Not-Monitored)
                  GW Interface Outside-Zone (912.168.123.26): Normal (Not-Monitored)
                  GW Interface management (331.1.1.46): Normal (Not-Monitored)          
SIMPLEASA1/sec/act#  sh failover | i \)\:|host
        This host: Secondary - Active
                  Interface Edge (912.168.22.17): Normal (Monitored)
                  Interface Inside (310.13.19.17): Normal (Monitored)
                  Interface EXT (912.168.50.17): Normal (Monitored)
                  Interface WIFI (912.168.11.17): Normal (Monitored)
        Other host: Primary - Standby Ready
                  Interface Edge (912.168.22.16): Normal (Monitored)
                  Interface Inside (310.13.19.16): Normal (Monitored)
                  Interface EXT (912.168.50.16): Normal (Monitored)
                  Interface WIFI (912.168.11.16): Normal (Monitored)                      
[..srv01]$ 

答え1

シェルは一重引用符で囲まれた文字列でawkにスクリプトを渡していますが、一重引用符があるようです。~へ台本も同じだ。実際には引用符付き文字列を終了します。

awk 'BEGIN  {F='[)#/(:]'; FS = "\n"; RS = ""; OFS = "|";fw="";dev=""} 
                ^^^^^^^ not quoted

シェルは引用符なしで1つを表示し、)構文エラーが発生します。とにかく、awkスクリプトで一重引用符を使用したくない場合は、構文エラーが発生します。突然。したがって、他の割り当てと同様に、二重引用符を使用すると、シェル内の一重引用符にフィットし、実際にawkコードで機能します。

awk 'BEGIN { foo="bar"; ...}'

次に、awkのオプションは代わりに変数であるフィールド区切り-F文字を設定することに注意してください。したがって、あなたがしたいと思うし、おそらく基本レコードの区切り文字を変更したくないでしょう。少なくとも上記の行では変更しませんでした。FSFBEGIN { FS="[)#/(:]"; ...RS


/usr/bin/awkあるいは、awkスクリプトをシェルスクリプトに入れる代わりに、シェルをスキップしてawkをスクリプトへのインタプリタとして直接作成することもできます(awkがそこにあると仮定)。

#!/usr/bin/awk -f
BEGIN { FS="[)#/(:]"; OFS="|"; fw=""; dev=""} 
{
    if ( $0 ~ /sh failover/ ) fw=$1 ; 
    if (($0 ~ /This host/) || ($0 ~ /Other host/)) dev=$2; 
    if ( $0 ~ /\)\:/ ) {
        print $2, $1, fw, dev
    } 
}

呼び出され、./script.awk実行可能な場合に実行できます./script.awk filename。つまり、ファイルを使用してスクリプトの引数として扱うことができます。

関連情報