オプションでデータの抽出

オプションでデータの抽出

txt ファイルには次のデータの塊があります。

Informatica(r) PMCMD, version [9.5.1 HotFix4], build [313.0217], SOLARIS 64-bit 
Copyright (c) Informatica Corporation 1994 - 2014   
All Rights Reserved. 

Invoked at Wed Dec 30 11:13:42 2015 

Connected to Integration Service: [TEST_Integration_Service].   
Integration Service status: [Running]   
Integration Service startup time: [Sun Dec 27 06:37:32 2015]  
Integration Service current time: [Wed Dec 30 11:13:42 2015]  
Folder: [ALS_DIM]  
Workflow: [wf_ld_als_dim] version [1].  
Workflow run status: [Scheduled]  
Workflow run error code: [0]  
Workflow run id [0].  
Schedule time: [Wed Dec 30 19:00:00 2015]  
Workflow run type: [Schedule]  
Run workflow as user: [Administrator]  
Run workflow with Impersonated OSProfile in domain: []  
Integration Service: [TEST_Integration_Service]  
Folder: [ALS_FACT]  
Workflow: [wf_s_m_ld_interchanges_detail_log] version [1].  
Workflow run status: [Scheduled]  
Workflow run error code: [0]  
Workflow run id [0].  
Schedule time: [Mon Jan 04 16:30:00 2016]  
Workflow run type: [Schedule]  
Run workflow as user: [Administrator]  
Run workflow with Impersonated OSProfile in domain: []  
Integration Service: [TEST_Integration_Service]  
Folder: [ALS_PRD]  
Workflow: [wf_maint_service_fields] version [1].  
Workflow run status: [Scheduled]  
Workflow run error code: [0]  
Workflow run id [0].  
Schedule time: [Thu Dec 31 07:10:00 2015]  
Workflow run type: [Schedule]  
Run workflow as user: [Administrator]  
Run workflow with Impersonated OSProfile in domain: []  
Integration Service: [TEST_Integration_Service]  
Number of scheduled workflows on this Integration Service: [3]  
Disconnecting from Integration Service  

繰り返されるたびに、フォルダ名、ワークフロー名、ワークフロー実行状態、スケジュール時間、統合サービス名のみが順番に抽出されるように、データを別のテキストファイルに抽出する必要があります。

たとえば、

Insert into <tablename> values('ALS_DIM', 'wf_ld_als_dim', 'Scheduled', 'Wed Dec 30 19:00:00 2015', 'TEST_Integration_Service')

これは最初のグループなどについてインポートする必要があります。

私は与えられた3つのデータセットに固有のスクリプトを開発しましたが、それを使用してスクリプトを必要な数のデータセットに対して実行できるはずです。

私はシェルスクリプトについて非常に基本的な知識を持っているので、これを助けてほしいと思います。

答え1

一方sed通行...

sed -ne'/^Folder: *\[/!{'                                     \
         -e'/^Workflow\( run status\)\{0,1\}: *\[/!{'         \
              -e'/^Schedule time: *\[/!{'                     \
                   -e'/^Integration Service: *\[/!d'          \
    -e\} -e\} -e\} -e"s//'/"      -e"s/\].*/'/"  -e'H;x'      \
                   -e'/ .*\n.*/h' -e's///'       -e'x'        \ 
                   -e's//Insert into <tablename> values(&)/'  \
                   -e's/\n//'     -e's//, /gp'

Insert into <tablename> values('ALS_DIM', 'wf_ld_als_dim', 'Scheduled', 'Wed Dec 30 19:00:00 2015', 'TEST_Integration_Service')
Insert into <tablename> values('ALS_FACT', 'wf_s_m_ld_interchanges_detail_log', 'Scheduled', 'Mon Jan 04 16:30:00 2016', 'TEST_Integration_Service')
Insert into <tablename> values('ALS_PRD', 'wf_maint_service_fields', 'Scheduled', 'Thu Dec 31 07:10:00 2015', 'TEST_Integration_Service')

したがって、最初の行は次の許容可能な一致を無効にします。

if ! match ^Folder: *\[
then  if ! match ^Workflow: *\[ or ^Workflow run status: *\[
      then if !  match ^Schedule time: *\[
           then  if !  match ^Integration Service: *\[
                 then  delete
                 fi
           fi
      fi
fi

ただし、ラインがチェーンの1つと一致すると、チェーンが切断され、最後まで移動できません。これは、指定された一致行に対してテストされた最後の正規表現が閉じる角括弧まで、その行の先頭を記述することを意味します。sedスクリプトでは、空のアドレスを使用して、最近コンパイルされた正規表現を再参照できます//。私はそれを変更し、s//'/必要な出力の先行引用符に置き換えます。'

残りは、必要なすべての情報と各行]の最初の行の後の後続のコンテキストだけです。そのため、各行の不要な尾も後続の引用符にs/\].*/'/置き換えました。'

この時点で、すべての線は目的の部分に削除されましたが、まだ接続されていません。これを達成するために、H行サイクルを維持する古いスペースを使用しました。したがって、各行のコピーをH前のスペースに追加し、x保存およびモードバッファを変更して/ .*\n.*/から<スペース>それから<改行>- 日付バーは、次のスケジュールされた行でのみ発生します。

パターンが見つかったら、h古いスペースを上書きしてs///置き換えます。みんなパターン空間(この繰り返しの最後の行なので、次の繰り返しのために空白のままにしてください。)。ここに空のアドレスがある場合、s///そのアドレスと一致する行の内容のみが削除されます。<スペース> + <改行>パターン - したがって、各反復の最後の行でのみこれらのコマンドが成功する可能性があります。

とにかく、後でx最後にホールドバッファとパターンバッファを変更したので、パターンバッファには、この繰り返しのすべての一致が次のように区切られて含まれます。<改行>それ以外の場合は、最も近い一致とゼロのみが含まれます。<改行>数値。これがこの反復の最後の一致行である場合、この点の保持バッファは空です。それ以外の場合は、これまで一致するすべての行が含まれ、各行には先行する接頭辞が付きます。<改行>

次に、同じ正規表現を再び引用し、次に置き換えようとしました。<スペース> + <改行>独自のパターンで包まれたInsert into <tablename> values(そして後続)

s///最後に、私は先頭を交換しません。<改行>最後に一致する行のパターン空間にあり、残りはすべて<改行>カンマの次<スペース>各。s///置換が成功すると、結果は標準p出力として印刷されます。

答え2

パール方法:

$ perl -lne 'if(/^(Folder|Workflow|Workflow.*?status|Sched.*time|Integration Service):.*?\[([^][]+)/){++$k%5==0 ? print "$2"  : printf "%s,",$2}' file
ALS_DIM, wf_ld_als_dim, Scheduled, Wed Dec 30 19:00:00 2015, TEST_Integration_Service
ALS_FACT, wf_s_m_ld_interchanges_detail_log, Scheduled, Mon Jan 04 16:30:00 2016, TEST_Integration_Service
ALS_PRD, wf_maint_service_fields, Scheduled, Thu Dec 31 07:10:00 2015, TEST_Integration_Service

またはもっと簡潔に言えば:

$ perl -lne '
 if(/^                       ## Match the beginning of the line
     (                       ## 1st capturing group: $1
      Folder               | ## The various things we want to match
      Workflow             | 
      Workflow.*?status    |
      Sched.*time          |
      Integration\s*Service
      ):                     ## Only if they are followed by a :
      .*?\[
      (                      ## 2nd caprturing group: $2.
        [^][]+               ## The longest string of non-] or [
      )/x                    ## The x allows writing multiline regexes          
    )
{                            ## If this line matches...
    $k=$k+1;                   ## Increment the counter $k by one
    if($k%5==0){               ## If the current value of $k is a multiple of 5.
      print "$2"               ## Print the 2nd captured group and a newline.
    }                          ## The newline is automatically added by the -l. 

    else{
      printf "%s,",$2         ## For other lines, just print with no newline.
    }
}' file
ALS_DIM, wf_ld_als_dim, Scheduled, Wed Dec 30 19:00:00 2015, TEST_Integration_Service
ALS_FACT, wf_s_m_ld_interchanges_detail_log, Scheduled, Mon Jan 04 16:30:00 2016, TEST_Integration_Service
ALS_PRD, wf_maint_service_fields, Scheduled, Thu Dec 31 07:10:00 2015, TEST_Integration_Service

を追加するには、Insert ...簡単なパスを渡すだけですsed

$ perl -lne 'if(/^(Folder|Workflow|Workflow.*?status|Sched.*time|Integration Service):.*?\[([^][]+)/){++$k%5==0 ? print "$2"  : printf "%s,",$2}' file | 
    sed "s/^/Insert into <tablename> values('/; s/,/','/g; s/$/')/"
Insert into <tablename> values("ALS_DIM","wf_ld_als_dim","Scheduled","Wed Dec 30 19:00:00 2015","TEST_Integration_Service")
Insert into <tablename> values("ALS_FACT","wf_s_m_ld_interchanges_detail_log","Scheduled","Mon Jan 04 16:30:00 2016","TEST_Integration_Service")
Insert into <tablename> values("ALS_PRD","wf_maint_service_fields","Scheduled","Thu Dec 31 07:10:00 2015","TEST_Integration_Service")

sed3つの代替演算子を実行します。

  • s/^/Insert into <tablename> values("/^行の先頭です。したがって、s/^/foo/行の先頭に挿入します。fooここに挿入していますnsert into <tablename> values("
  • s/,/','/g:(s///g)コンマをすべてに置き換えます','
  • s/$/")/'$行の終わりなので、)"最後に追加されます。

関連情報