テキスト処理ブロック行から列まで

テキスト処理ブロック行から列まで

Solarisのリストを含むファイルがあります。

List A
hi
hello
hw r u

List B
Hi
Yes

List C
Hello

リストを次のように置き換える必要があります。

List A    List B    List C
hi        Hi        Hello
hello     Yes
hw r u

Solarisでこれを行うにはどうすればよいですか?

答え1

awk各チャンクを別々のファイルに分割して一緒に入れることができますpaste(以下では、各リストの間に常に空白行があるとします)。

awk '/^$/ {N++;next}{print >"file"N}' infile.txt
paste file*

pasteコマンドをに移動することもできますawk

awk '/^$/ {N++;next}{print >"file"N} END{system("paste file*")}' inile.txt

出力は次のとおりです

List A    List B    List C
hi        Hi        Hello
hello     Yes
hw r u

行の長さを変更すると、次のような美しいインデントが生成されます。

入力ファイル:

list A
hi
hello
hw r u

List B
Hi this is list B
Yes

List C
Hello, this is list C

あなたはできますpaste file* |column -s $'\t' -tn結果が得られます:

list A  List B             List C
hi      Hi this is list B  Hello, this is list C
hello   Yes
hw r u

答え2

以前の回答に加えてcsplitまた、同じ方法でファイルを分割し、そのコマンドを使用して目的のpaste出力を取得するコマンドもあります。

csplit -zs -f outputfile inputfile '/^List/' '{*}'
paste outfile*
  • '/^List/'ファイルを一致させ、次の新しいファイルに分割するパターン。
  • '{*}'パターンをできるだけ繰り返す
  • -z空の出力ファイルを削除するために使用され、-s出力ファイルサイズの数を印刷しないために使用されます。
  • -fカスタムプレフィックスを定義するために使用されます。結果ファイル####デフォルトは2桁で、次のように定義できます。 (-n NNは、定義された接頭辞の後の接尾辞の桁数です。)

答え3

牛に似た一種の栄養アッ方法:

awk 'BEGIN{ max=0 }
     /^List/{ if(k && k>max) { max=k; idx=c } ++c; k=0 }
     NF{ a[c][++k]=$0 }
     END{ 
         for(i=1;i<=max;i++) 
             for(j=1;j<=c;j++) printf "%s%s",a[j][i],(j==c)?ORS:"\t" 
     }' file | column -ts$'\t'

出力:

List A  List B  List C
hi      Hi      Hello
hello   Yes
hw r u

答え4

注文する

for i in "List A" "List B" "List C"; do sed -n "/$i/,/^$/p" h.txt >"$i.txt"; done

paste List\ *

出力

List A  List B  List C
hi  Hi  Hello
hello   Yes 
hw r u      

関連情報