特定の単語で始まる行を印刷し、残りのレコードでは最初のフィールドのみを印刷したい

特定の単語で始まる行を印刷し、残りのレコードでは最初のフィールドのみを印刷したい

例えば:

CREATE TABLE MWWDATA."VTCat02" (
    "ID" NUMBER(10) DEFAULT NULL ,
    "Cat" VARCHAR2(255) DEFAULT NULL ,
    "Style_Code" VARCHAR2(255) DEFAULT NULL ,
    "Vendor_Style_#" VARCHAR2(255) DEFAULT NULL );

上記の例では、CREATE TABLE で始まる行を印刷し、残りの行には最初のフィールドのみを印刷します。

次のような出力が欲しい

CREATE TABLE MWWDATA."VTCat02" ("ID","Cat","Style_code","Vendor_Style_#");

答え1

awk

awk '/^CREATE TABLE/{
       inside = 1
       sep = ""
       printf "%s", $0
       next
     }
     inside {
       printf "%s", sep $1
       sep = ","
       if (/\);$/) {
         print ");"
         inside = 0
       }
     }'

CREATE TABLEこれは、行の先頭で で始まり、行の末尾で で終わるステートメント);(同じ行ではない) と、各列名が後続の行の最初のフィールドである (つまり、列名に空白を含めることができない) ことに依存します。

答え2

次のような仕事のようですperl:

perl -0777 -pe 's{(CREATE TABLE \S+\s+)\K(\((?:(?2)|.)*?\))}
  {"(" . join(",", $2 =~ /".*?"/g) . ")"}gse'

(引用符で囲まれた文字列に一致しない括弧が含まれておらず、 が比較的新しいバージョンであることが前提ですperl)。

内訳:

  • -0777レコードセパレータを0777(あり得ないバイト値)に設定し、実質的に啜るperl入力全体に対して全体として作用するモード。
  • -pe 'code':sedモード。(eコードを評価するexpressionを1レコードずつ実行し、p後で印刷します。
  • s{...}{...}gse: 代わりの局所的に、文字列をs単一行(.改行文字にも一致)であり、置換はperlとして扱われますe表現するe評価する。
  • \K: 3月置換する部分の開始位置です。
  • (?2): 再帰正規表現を実行する 1 つの方法です。ここでは、2 番目のグループで囲まれた正規表現が含まれます(...)。つまり\((:(?2)|.)*?\)、は、(さらにグループまたはその他の文字のシーケンス(...)(可能な限り少ない) が続き、その後に が続きます)
  • join(",", $2 =~ /".*?"/g)".*?"一致する文字列(つまり、引用符で囲まれた文字列)のリストを$2コンマで結合します。

答え3

使用方法awk:

awk '{if (NR==1) {printf "%s", $0} else {printf "%s,",$1}} END {printf "^H);\n"}' /tmp/inputfile

入力の最初の行にある場合は最初に一致し、その場合は行全体を出力し、そうでない場合は最初の単語とそれに続くコンマを出力します。

最後のステップとして、バックスペースを出力して最後のカンマを削除し、閉じ括弧と改行を出力します。バックスペース文字は、 を使用してコマンドラインに挿入されますctrl+vctrl+hctrl+hキーはアルファベットの 8 番目の文字 (H) に対応し、キーコード 8 はバックスペースに対応します。

出力は次のようになります。

CREATE TABLE MWWDATA."VTCat02" ("ID","Cat","Style_Code","Vendor_Style_#");

関連情報