web-dev-qa-db-ja.com

ブロックの行から列へのテキスト処理

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でこれを行うにはどうすればよいですか?

3
John

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
3
αғsнιη

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

csplit -zs -f outputfile inputfile '/^List/' '{*}'
paste outfile*
  • '/^List/'は、そこにあるファイルを一致させて次の新しいファイルに分割するパターンです。
  • '{*}'パターンをできるだけ繰り返します
  • -zは、空の出力ファイルを削除するために使用されます。 -sは、出力ファイルサイズのカウントを出力しないために使用されます
  • -fは、カスタムプレフィックスoutputfile ##を定義するために使用されます。ここで、##はデフォルトで2桁ですが、-n N(Nはサフィックスの桁数)で定義できます。定義されたプレフィックスの後)
1
αғsнιη

コマンド

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      
0