2017-03-28 5 views
3

複数行にまたがるレコードを処理する必要があります。たとえば、複数行レコードを1行に変換してから、必要なものをすべて取得する必要があります。レコードの境界が明確でないため、RS\n\nに設定するだけではありません。私が区画さレコードを取得したら、私はRSを設定することができますレコードが区切られていないときに複数行レコードを1行に作成する

awk '{gsub(/^constant_string/,"\n&")}1' input 

constant_string bla bla1 
bla bla bal 
fooo foooooo baaar 

constant_string bla1 bla2 
abcd cdfe fghi jkhil 
foo bar bar bar bar bar bar 

constant_string bla bla3 
random data is present 

:これを達成するために

cat input 
constant_string bla bla1 
bla bla bal 
fooo foooooo baaar   #End of record 1 
constant_string bla1 bla2 
abcd cdfe fghi jkhil 
foo bar bar bar bar bar bar #End of record 2 
constant_string bla bla3 
random data is present  #End of record 3 

、私は次のように二つのレコードの間に新しい行を追加することによって、上の画定にこれらの未画定レコードを変換しました\n\nにして、私が必要とするものは何でもしてください。

awk '{gsub(/^constant_string/,"\n&")}1' input |awk -v RS= '{$1=$1}1' 
constant_string bla bla1 bla bla bal fooo foooooo baaar 
constant_string bla1 bla2 abcd cdfe fghi jkhil foo bar bar bar bar bar bar 
constant_string bla bla3 random data is present 

質問:私は2つのステップを使用してソリューションを実現することができる午前

、それはそれをawkの内の1つのステップを行うことが可能ですか?

は、私は次のよう試みたが、うまくいきませんでした:

awk -v RS="" '{gsub(/^constant_string/,"\n&")}1' input 
awk -v RS="" '{$0=gensub(/^constant_string/,"\n&",$0)}1' input 
+1

をはいそれは可能ですが、それはスクリプト内の余分な解析につながります。ストリーミングされたバージョンのほうがはるかに優れています。おそらく、最初のビットのためにsedに入れ替えてください。例: '

答えて

2

bに転送してconstant_stringENDに処理するとどうなりますか? functionを使用して:あなたはGNU AWKを持っている場合

$ awk ' 
function process(str) { if(str!="") print str } 
    /^constant_string/ { process(b); b=$0; next } 
         { b=b OFS $0 } 
        END { process(b) } 
' file 
constant_string bla bla1 bla bla bal fooo foooooo baaar 
constant_string bla1 bla2 abcd cdfe fghi jkhil foo bar bar bar bar bar bar 
constant_string bla bla3 random data is present 
+2

'if(str!=" ")'ではなく 'if(str)'を使います。これは、strが数値的にゼロに評価されたときに失敗するためです。 'print b'ではなく' print str'を使うか、関数の引数を気にしないでください。 –

1
awk 'BEGIN{ RS="(^|\n)constant_string"} 

    # filtering to avoid "empty" record 
    /./ { 
     # $1 is first "word" (FS is default) AFTER your constant string that is 
     # "removed" of $0 as Record separator. 
     # Info, this is now a multiline record 

     #... treat what you want 
     print " -- " NR : [" $0 "]" 
     for (i=1;i<=NF;i++) print NR "." i " : " $i 

     } 
    ' YourFile 

注:

  • はawkのバージョンに依存、POSIXは、セパレータとして、文字列内の任意のcharとしてRS文字列を取るように見えますここでgawkは文字列(この場合は正規表現として)を取る
  • 正規表現のメタキャラクターである特殊なchharをエスケープするにはconstant_stringを確認してください
+0

POSIXはセパレータとして** RSの最初の**文字を使用します。 –

0

はこれを試してみてください -

awk 'NR>1{gsub(/\n/," "); print RS$0}' RS='constant_string' f 
constant_string bla bla1 bla bla bal fooo foooooo baaar 
constant_string bla1 bla2 abcd cdfe fghi jkhil foo bar bar bar bar bar bar 
constant_string bla bla3 random data is present 
関連する問題