単一行パラメータに基づいてテキストファイルから行を抽出する

単一行パラメータに基づいてテキストファイルから行を抽出する

私はスクリプトに初めて触れたので、助けてくれてありがとう。場合によっては、かなり長いテキストファイルがあり、テキスト行の各部分の長さは約6/7行です。これはログファイルで、各セクションはタイムスタンプという単語で始まります。各行の間には空行があります。各プロファイル行はセミコロンで終わります。

timestamp=201706291035.....;
  line 2;
  line 3;
  line 4;
  line 5;
  line 6;
  line 7;

timestamp=201706291038.....;
  line 2;
  line 3;
  line 4;
  line 5;
  line 6;

1行の各セクションを別のテキストファイルに抽出できる必要があります。最後のセミコロンなしで使用することをお勧めします。

timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6

この情報は解決策を見つけるのに十分ですか?

以下は簡単な例です。


タイムスタンプ=2017-06-28-01.01.35.080576;
ユーザーID = user1
;アプリケーション
ID = 10.10.10.10.11111.12345678901;


タイムスタンプ = 2017-06-28-01.01.36.096486;
ユーザーID = user1
;アプリケーション
ID = 10.10.10.10.11111.12345678901; table.field, table.field ここで table.field = 値


@steeldriverスクリプトを実行した後、ソースファイルとターゲットファイルは同じように見えます。

答え1

これは、次のように慣用的なawkを使用して実行できます。

awk '$1=$1' RS= OFS= infile

出力:

timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;

説明する

ここにはたくさんのものが含まれています。基本的には3つのステップがあります。

  1. RSまず、入力はレコード区切り文字()に基づいてレコードに分割されます。
  2. 各レコードは、フィールド区切り文字(FS)に基づいて複数のフィールドに分割されます。
  3. 印刷時に、出力フィールド区切り記号(OFS)がフィールド区切り文字として使用されます。

awkが入力を解析すると、いくつかの暗黙の規則が適用されます。データはレコードごとに区切られ、一度に1レコードずつ読み取られますRS(デフォルトは\n)。RS上記の例のように空の場合は、空行でレコードを区切ります。したがって、各部分はレコードとして読み込まれます。

強制的にawk置き換えるには、最初のフィールドをそれ自体に設定します。FSOFS$1

編集する

指摘したとおりスチールドライバー、OPは末尾のセミコロンを削除しようとします。恥ずかしい盗作:

awk '{ sub(/;$/,"",$NF); $1=$1 } 1' RS= OFS= infile

答え2

これは次の方法で行うことができます。

perl -lF';\n?' -00ne '$,=";"; print @F' yourfile

出力

timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6

布材

  1. パールオプション

    a) -l=> ORS="\n" + RS = "\n"

    b) -F';\n?'=>はFSをセミコロンにし、その後にオプションの改行文字が続きます。

    c)-00=>はRS =を作成して短絡モードを有効にします。

    d) -n=> 暗黙的なファイルの読み取り + 明示的な印刷が有効になります。

  2. メイン:現在のレコードによって区切られたフィールドである$,=;OFSにセミコロンが追加されます。@F$_FS

答え3

タイムスタンプの前に空白行があると簡単

perl -pe 'chomp unless /^$/'

改行文字がない場合は、前の行を覚えておく必要があります。

perl -pe 'chomp; print "\n" if $. > 1 && /^timestamp=/; print }{ print "\n"'

答え4

ただこんな方法だからsed

この文を出発点にしてくださいPeter KruminsによるSedの専門用語の説明、パート1:ファイル間隔、番号付け、テキスト変換および置換

  1. 行がバックスラッシュ「\」で終わると、次の行に追加されます。

    sed -e :a -e '/\\$/N; s/\\\n//; ta'
    

最初の式「:a」は、名前付きラベル「a」を作成します。 2番目の式は、現在の行がバックスラッシュ「\」で終わっていることを確認します。存在する場合は、「N」コマンドを使用して次の行に関連付けます。次に、「s/\\n//」コマンドを使用して、接続行間のスラッシュと改行を削除します。置換が成功したら、式の先頭に分岐し、別のバックスラッシュがある可能性があることを望みながら、同じことをやり直してください。交換に失敗すると、行はバックスラッシュで終わらずに印刷されます。

先行スペースを維持しても削除するために交換を交換して調整すると、\\次のような結果が得られます。;;

$ sed -e :a -e '/;$/N; s/\n *//; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;

timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;

閉鎖!今、空の行を絞ります。パターンをテストしてこれを実行できます。終わる改行(つまり、追加された行が空)で、次の場合に印刷します。に従って改行後のパターンの削除:

$ sed -e :a -e '/;$/N; /\n$/{P;d;}; s/\n *//; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7;
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6;

今、私たちは次のものを切り取るだけです;。これを行う1つの方法は、パターンスペースに追加するときに各行を削除し、改行を削除しながら;再挿入することです。

$ sed -e :a -e '/;$/{s///;N;}; /\n$/{P;d;}; s/\n */;/; ta' infile
timestamp=201706291035.....;line 2;line 3;line 4;line 5;line 6;line 7
timestamp=201706291038.....;line 2;line 3;line 4;line 5;line 6

すでに改行文字を食べているため、最後の項目は;再挿入されないため、{P;d;}代替項目はs//\n /;/適用されません。

関連情報