各出力行がブロックタイトルで始まるようにテキストをどのように変換できますか?

各出力行がブロックタイトルで始まるようにテキストをどのように変換できますか?

以下を変換するには、スクリプトを作成する必要があります。

Name = x:y
Z =  a:b.c
Z1 = a1:b1.c1
End
Name=x1:y1
Z2 = a2:b2.c2
Z3 = a3:b3.c3
Z4 = a4:b4.c4
End
Name = l:k
s = w:e.v
End

入力する:

x:y Z    a:b.c
x:y Z1   a1:b1.c1
x1:y1   Z2   a2:b2.c2
x1:y1   Z3   a3:b3.c3
x1:y1   Z4   a4:b4.c4
l:k s    w:e.v

答え1

=オプションの周囲のスペースを区切り文字として使用します。

awk -F '[[:blank:]]*=[[:blank:]]*' '
    $1 == "Name" {name = $2; next}
    $1 != "End"  {print name, $1, $2}
' filename

はい

これらの解決策を見ると、awk進行状況が少し混乱していることがわかります。正しく配置された印刷ドアを挿入すると、何が起こっているのかを視覚的に見ることができます。

$ awk -F '[[:blank:]]*=[[:blank:]]*' '
      $1 == "Name" { name = $2; print "--NAME: "$2; next }; 
      $1 != "End" { print " --END: "name,$1,$2 }
' sample.txt

次の出力が生成されます。

--NAME: x:y
 --END: x:y Z a:b.c
 --END: x:y Z1 a1:b1.c1
--NAME: x1:y1
 --END: x1:y1 Z2 a2:b2.c2
 --END: x1:y1 Z3 a3:b3.c3
 --END: x1:y1 Z4 a4:b4.c4
--NAME: l:k
 --END: l:k s w:e.v

答え2

使用方法

この小さなsedコマンドがアクションを実行します。

sed -ne '
  /^Name */{
    s/^.*= *//;
    h;
    tb;
  };
  /^End/bb;
  G;
  s/^\(.*\) *= *\(.*\)\n\(.*\)$/\3\t\1\t\2/p;
  :b
  ' <sourcefile.txt 
x:y Z       a:b.c
x:y Z1      a1:b1.c1
x1:y1       Z2      a2:b2.c2
x1:y1       Z3      a3:b3.c3
x1:y1       Z4      a4:b4.c4
l:k s       w:e.v

説明する:

  • 行が次から始まる場合名前、まで減少=その後、タグに保存しhold spaceてタグに移動します:b
  • 行が次から始まる場合終わり、ラベルまで次の手順をスキップします:b
  • ラベルの前:b(他の場合):、hold spacethan追加もしこの行は `文字列と一致し、その後には任意の数のスペースと等号、いくつかのスペース、2番目の文字列、改行文字、最後に3番目の文字列が続きます。それから3番目の文字列の後にタブ文字を印刷します。最初の文字列はタブ文字で、次に2番目の文字列です。

そしてちょうど使用する方法

while read line ;do
    if [ ${line//=*} = "Name" ] ;then
        name=${line//*=}
    else
        [ "${line//=*}" != "$line" ] &&
            printf "%s\t%s\t%s\n" $name ${line//=}
    fi
  done <sourcefile.txt 
x:y Z       a:b.c
x:y Z1      a1:b1.c1
x1:y1       Z2      a2:b2.c2
x1:y1       Z3      a3:b3.c3
x1:y1       Z4      a4:b4.c4
l:k s       w:e.v

答え3

これはパールです:

perl -ne 'if(/^Name\s*=\s*(.+)/){$n=$1;}else{print "$n $_" unless /^End/}' file

説明する

perl -ne入力ファイルを1行ずつ処理し(-n)、各行を変数に保存し、引数として指定されたスクリプトを$_実行することを意味します-e

if(/Name\s*=\s*(.+)/){$n=$1;}:行Name = <something>。で始まる場合。<something>として保存します$n

それ以外の行で始まらない場合は、行が始まらない限り、現在の値、名前、および行の残りの部分がName印刷されます。$nEnd

関連情報