質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Q&A

解決済

1回答

1203閲覧

Bash:連続する空白文字によって作られたテキストデータを整形したい

pwq

総合スコア23

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

0グッド

0クリップ

投稿2021/10/14 07:26

編集2021/10/14 07:36

下記のような条件でテキストデータを整形したいです。どのような手段なら可能でしょうか?

#条件
*それぞれの列は連続した空白によって区切られる
*各列の先頭(までの文字数)は揃っている
*列と列の間の空白数は一定ではない
*列数はあらかじめ分かっている
*各列の開始文字位置はあらかじめ分かっていない
*一列目に文字が現れてから次に一列目に文字が現れるまで、同じ列の文字を一塊にまとめる(例と出力参照)

#例(□は空白)
あいう□□□□□かきく□□□□□□□□□□
□□□□□□□□けこさ□□□□□□□□□□なにぬ
□□□□□□□□□□□□□□□□□□□□□ねの
たちつ□□□□□まみむ□□□□□□□□□□
□□□□□□□□めも□□□□□□□□□□□らりる
てと□□□□□□□□□□□□□□□□□□□れろ

#期待する出力
あいう\tかきくけこさ\tなにぬねの
たちつ\tまみむめも\tらりる
てと\t\tれろ

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KojiDoi

2021/10/14 08:33

bashでないと駄目なんですか? perlなら割と簡単だと思うんですが。
pwq

2021/10/14 10:51

perlでも大丈夫です!
guest

回答1

0

ベストアンサー

要は、

  • 各行を列幅固定で列に分割。
  • 列データの前後に桁合わせのために入っている空白は除去。
  • 第1列目に空白しか含まれていない行については、各列のデータを全行のデータにそれぞれマージする。

ということだと理解しました。

シェルスクリプトでもcutとかsedとか駆使すれば出来るかもしれませんが、こういう処理はperlが一番効率的でしょう。

test.txt

あいう□□□□□かきく□□□□□□□□□□ □□□□□□□□けこさ□□□□□□□□□□なにぬ □□□□□□□□□□□□□□□□□□□□□ねの たちつ□□□□□まみむ□□□□□□□□□□ □□□□□□□□めも□□□□□□□□□□□らりる てと□□□□□□□□□□□□□□□□□□□れろ

test.pl

my $spc='□'; # チェックの便宜上「四角記号」を空白と見做して処理する my @data; while(<>){ chomp; my(@f) = /(.{8})(.{13})(.*)/; # 列幅固定でデータ分割して取り込み map {s/^${spc}*//; s/${spc}*$//;} @f; # 各列の頭とお尻の空白を削除 if($f[0]=~/^${spc}*$/){ # 先頭列に空白しか含まれていない→直前行のデータにマージ for(my $i=0; $i<=$#{$data[-1]}; $i++){ $data[-1][$i] .= $f[$i]; } }else{ #先頭列に空白以外あり→新しい行を追加 push(@data, \@f); } } # 出力 map {print join("\t", @$_), "\n"} @data;

コマンドラインで以下のように実行。

perl -CSDA -Mutf8 -l test.pl test.txt

投稿2021/10/14 12:17

KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2021/10/14 12:36

> *各列の開始文字位置はあらかじめ分かっていない が考慮されていないようです。
KojiDoi

2021/10/14 13:07

> *各列の開始文字位置はあらかじめ分かっていない それは、各列の先頭に何個か空白が入るかもしれないという話でしょう。列幅固定であれば、分割した後に前後の空白を削除することでクリアできるはずです。
otn

2021/10/14 13:19

8とか13とかははあらかじめ分かっていないと言うことでは? まあ、ファイルを人間が目で見て、8とか13を判断してからコードを書き換えると言うことでもいいのかもしれませんが。
KojiDoi

2021/10/14 13:26

>8とか13とかははあらかじめ分かっていないと言うことでは? 質問の出力例から考えて、そこは始めから分かっているのだろうと解釈しました。逆にそうでなければ情報が足りないので処理は不可能ですね。
pwq

2021/10/14 13:46

ありがとうございます。unixのpdftotextでセル内に改行がある表を読み込んだ時、質問のような状態になってしまい解決策を探していました。挙げて頂いたコードを解読しながら頑張ってみます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問