テキスト処理ラインは行から列までAwkをブロックします。

テキスト処理ラインは行から列までAwkをブロックします。

以下の入力ファイルがあります。 o / pが述べたように、テキスト形式を再指定する必要があります。私はこのフォーラムで得られたawkを使用していますが、リストAの列番号に基づいています。助けてください

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" 
 }' filename | column -ts$'\t'  

入力する:-

List A
Hello
how are you
fine

List B
good: Fine_health
hello: world_free
some: unkon_text
some: unkon_text1
some: unkon_text2

期待される出力

List A       List B
Hello        good: Fine_health
how are you  hello: world_free
fine         some: unkon_text
             some: unkon_text1
             some: unkon_text2

答え1

使用幸せ(以前のPerl_6)

~$ raku -e 'my @a = slurp.split("\n\n"); @a.=map(*.split("\n", :skip-empty));  \
            my $length = @a>>.elems.max;  for ^$length -> $i {  \
               print ($_[$i] // q[ ]) ~ q[|] for @a; "".say;    \
               };'  filename.txt  |  column -ts'|'

上記の答えはRakuでコーディングされました。行はslurp(一度読み取る)とsplit段落(\n\n)で構成されています。段落は配列に割り当てられます@a。次の文では、各段落要素が行\nで区切られています。max配列の要素の長さを計算します。elems@a

@aその後、配列の各位置(読み取り:段落)printが最大maxとしてエクスポートされ、$length各位置(読み取り:行)の子要素が定義されていない(//"define or"演算子を使用して)、スペースがq[ ]挿入されました( "プレースホルダ" "文字"列)。列は~末尾の|列に関連付けられ、各行は終了します(改行文字を使用"".say;)。

OPに必要な出力を提供するために、Unixユーティリティをcolumn使用して挿入された|バー区切り文字の列を分割します。 Raku専用ソリューションの場合、置き換えるとタブ区切りの出力が~ q[|]返されます。~ qb[\t]

入力例:

List A
Hello
how are you
fine

List B
good: Fine_health
hello: world_free
some: unkon_text
some: unkon_text1
some: unkon_text2

出力例:

List A        List B
Hello         good: Fine_health
how are you   hello: world_free
fine          some: unkon_text
              some: unkon_text1
              some: unkon_text2

https://raku.org
https://rakudo.org

答え2

入力と出力の例は、両方のリストをリンクしようとしていることを意味します。これを行うためにawkは必要ありません。入力ファイルをlistとlistbの2つに分割し、貼り付けコマンドを使用してリンクします。

paste lista listb

入力ファイルを自動的に2つのファイルに分割し(各部分が1つまたは2つの空行で区切られていると仮定して)、空白のRSオプションでawkを使用できます。

awk -v RS= '{print > ("list" NR ".txt")}' listall

これにより、list1.txt および list2.txt ファイルが生成されます。

それから:

paste list1.txt list2.txt

答え3

公開されたスクリプトはいいえ働く最初の4行だけを印刷します。リストBの最後の2行は省略される。

問題は、k各リストの行数を数えることです。しかし、それはmax次にのみ保存されます。スタート各リストの長さなので、2番目のリストの長さは考慮されません。

回避策は、if(k && k>max) { max=k; }最後のリストを読んだ後、ENDブロックの最初の行に繰り返すことです。

これは別のエラーを明らかにします。最後の 2 行は列にリストされず、列 1 に表示されます。問題は、column長さ0の最初の列が認識されないようです。.各値の先頭に a を強制的に適用すると、列に B が正しくリストされます。

個人的に私はawkで劣化したいです。各列の項目の最大長を保存し、%-*s幅指定子で区切ります。おそらく、これは未使用の変数idxの目的です。

編集:はい、明らかに列の間違いです。このタブは作業用ですFourが、無視用ではありませんThree

先行および反復区切り文字をサポートするオプションがありますが、-nDebian拡張で文書化されています(そして私のMint(Ubuntu)ディストリビューションでも動作します)。そうでない場合、-nnull値は削除され(つまり、最初の行と最後の行の区切り文字は無視され)、隣接する複数の区切り文字がマージされます。

$ cat -vet foo
One$
 Two$
^IThree$
q^IFour$
$ column -t -s $'\t' foo | cat -vet
One$
 Two$
Three$
q      Four$

編集2:このバージョンにはより多くの機能があります。

(a)内部的にテーブル作成を実行してコマンドエラーを回避しますcolumn(また、データセット全体をメモリに格納するためのawkと列の追加プロセスとメモリのオーバーヘッドを防ぎます)。

(b)複数のファイル引数を受け入れます(デフォルトでは標準入力なのでパイプラインで動作します)。

(c) 2 つではなく、必要な数の出力列で動作します。

(d)元のリリースのバグを修正しました(最も右側の列の長さは無視されました)。

#! /bin/bash

Awk='
BEGIN { Gap = 2; }
/^List/ { ++col; row=0; }
NF { X[++row, col] = $0;
    if (mxrow < row) mxrow = row;
    if (len[col] < length($0)) len[col] = length($0);
}
function Column (Local, r, c) {
    for (r = 1; r <= mxrow; ++r) {
        for (c = 1; c < col; ++c) 
            printf ("%-*s", Gap + len[c], X[r,c]);
        printf ("%-s\n", X[r,c]);
    }
}
END { Column( ); }
'
    awk "${Awk}" "${@:-}" 
    

関連情報