一致する文字列からN番目の行を削除する(複数回発生しますが、最初の発生のみを削除)

一致する文字列からN番目の行を削除する(複数回発生しますが、最初の発生のみを削除)
CPUNAME AGENT_1
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_2
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  TIMEZONE abc
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_3
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


DOMAIN MASTERDM
  *MANAGER AGENT_1
  ISMASTER
END
  1. 上記のファイルでは、最初にパターンマッチング「TYPE」の後に「IGNORE」行を追加しました。

    sed -i '/^    TYPE.*/a IGNORE' filename 
    
  2. 特定のCPU(AGENT_1 AGENT_3など)のIGNOREフラグを削除する必要がありますが、IGNOREの場所は上記のように固定されていません。他のブロックの数字8、9、6がまもなくリリースされる予定です。現在、IGNOREフラグは場所8のファイルを編集しているCPUを知っているので、ループを使用してforIGNOREを削除します。

    for s in `cat $INPUT_FILE | awk '{print $1}'`; do
            echo $s
            sed -i "/$s/!b;n;n;n;n;n;n;n;d" Filename
    done
    
  3. 私が知っている限り、NODEの位置はすべてのブロックに対して常に固定されているので、次のコマンドを使用して行を置き換えました。

    for n in `cat $INPUT_FILE`; do
        CPU=$(echo $n | cut -f1)
        NODE=$(echo $n | cut -f2)
        echo "$CPU"
        echo "$NODE"
        sed -i "/$CPU/!b;n;n;n;c $NODE" filename
    done
    

上記のすべては、特定のCPUの無視を削除することを除いて、うまく機能します(固定行ではない場合)。ソリューションを改善するための貴重な提案を送ってください。

ベストアンサー1

処置: IGNORECPU名を指定する行の削除

行を削除するには、IGNORE次のものを使用できます。AGENT_1AGENT_3

awk '$1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3") { x=1 }
/^END$/ { x=0 }
x && /^ *IGNORE$/ { next }
1' inputfile

必要に応じて、基準からCPU名を追加または削除できます。

これにより、変更されたデータが標準出力として印刷されます。一般に、問題が発生するとデータが失われる可能性があるため、内部編集はお勧めできません。入力ファイルを内部編集をサポートしていないツールに置き換えたい場合は、いつでも次のようなものを使用できます。

awk 'some script' inputfile > tempfile && mv tempfile inputfile

説明する

  • $1 == "CPUNAME" && ($2 == "AGENT_1" || $2 == "AGENT_3")最初のフィールドがCPUNAME指定された名前の1つで、2番目のフィールドが指定された名前の1つである場合、条件は一致します。
  • { x=1 }このブロックから削除する項目をx表示するフラグを設定します。IGNORE
  • /^END$/ { x=0 }ライン全体がブロックの終わりにあるクリアフラグと一致する場合ENDx
  • x && /^ *IGNORE$/フラグが設定されている場合にのみ、先行スペースがある行IGNOREを一致させる条件です。x
  • { next }行の追加処理をスキップします。つまり、印刷しません。
  • 1trueデフォルト操作がない(=行あたり)条件print。 (例えば、より詳細に書くことができます{ print }。)

質問の入力例を使用してください。

CPUNAME AGENT_1
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_2
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  TIMEZONE abc
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_3
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


DOMAIN MASTERDM
  *MANAGER AGENT_1
  ISMASTER
END

出力は次のとおりです

CPUNAME AGENT_1
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_2
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  TIMEZONE abc
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_3
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


DOMAIN MASTERDM
  *MANAGER AGENT_1
  ISMASTER
END


反対のアクション:IGNORE行の挿入

実際の入力ファイルにIGNORE行がない場合は、指定されたCPU名と一致する(または一致しない)行の後のブロックにのみ行を挿入するスクリプトを使用することもできますTYPE

例:IGNOREどちらも一致しないブロックを挿入し、AGENT_1AGENT_3

awk '$1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3") { x=1 }
/^END$/ { x=0 }
1
x && $1 == "TYPE" { print "    IGNORE" }' inputfile

説明する:(最初のスクリプトとのみ異なる)

  • $1 == "CPUNAME" && ($2 != "AGENT_1" && $2 != "AGENT_3")最初のフィールドCPUNAMEと2番目のフィールドには名前がありません。
  • x && $1 == "TYPE"フラグがxセットされ、最初のフィールドはTYPE
  • { print " IGNORE" }ライン印刷IGNORE(TYPEライン後)

AGENT_1CPUを使用した入力例..AGENT_4と行なしIGNORE

CPUNAME AGENT_1
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_2
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  TIMEZONE abc
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_3
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_4
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


DOMAIN MASTERDM
  *MANAGER AGENT_1
  ISMASTER
END

結果出力:

CPUNAME AGENT_1
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_2
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
  TIMEZONE abc
  DOMAIN MASTERDM
  FOR MAESTRO
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_3
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


CPUNAME AGENT_4
  DESCRIPTION "MANAGER CPU"
  OS UNIX
  NODE xxxxxxxxx.xxx.xxx.cxx TCPADDR 31111
    TYPE MANAGER
    IGNORE
    AUTOLINK ON
    BEHINDFIREWALL OFF
    FULLSTATUS ON
END


DOMAIN MASTERDM
  *MANAGER AGENT_1
  ISMASTER
END

おすすめ記事