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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

2264閲覧

テキストファイルをcsvファイルに変換したい

01294941

総合スコア8

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/11/27 03:43

https://drive.google.com/file/d/1zI_3gYRx0V8tQHZ94TdhXsLhKDLpyP2j/view?usp=sharing

上のリンクに変換したいテキストファイルを置きました。

SZ VZ VA LAD BRF_toc BRF_toa
10 30
0
0.004976
0.076048 0.080558
10 30
0
0.04976
0.071202 0.075713

上から数行を抽出したものです。
4行で1セットになっています。

これを
SZ VZ VA   LAD    BRF_toc   BRF_toa
10 30 0 0.004976  0.076048   0.080558
10 30 0 0.04976  0.071202   0.075713
. . . . . .
. . . . . .
. . . . . .
このように合計4840行のcsvファイルにしたいです。

こんな並びの汚いテキストファイルだと都合よく変換することはできないのでしょうか。
詳しい方がいたら教えていただきたいです。

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

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

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

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

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

Zuishin

2021/11/27 03:50

それ CSV なんですか?
BeatStar

2021/11/27 04:31 編集

CSVファイルとは何でしょうか。無知な私に教えてくださいませんか?
can110

2021/11/27 04:56

その「汚い」ものを「都合よく」変換するルールを提示ください。 そうすると回答得られやすくなると思います。
Zuishin

2021/11/27 05:17

CSV ではなく固定長フォーマットに見えます。 もしそうであるならそのように書き換えないと、求めていない回答しかつかないでしょう。
melian

2021/11/27 05:30

このデータは何らかのプログラムから出力されたものではないでしょうか? もしくはデータベースから SQL などを用いて抽出したものなのかもしれませんが、データの作成方法が判明すれば対処方法も変わるかもしれません。
jinoji

2021/11/27 05:53 編集

この後どのように使うつもりなのかによっても、取るべき方法は変わってくるかも。 それによって、CSVがいいのか固定長がいいのか、あるいはそれ以外の選択肢を選ぶ方がいいのかを 判断することができるかもしれないですね。
1T2R3M4

2021/11/27 06:36

質問は 出来るか 出来ないか を知りたいってことですか。 それとも作業依頼ですか。
01294941

2021/11/27 14:24

たくさんのコメントありがとうございます。 テキストファイル自体はモデルを複数回回してその結果を出力したものです。 これをルックアップテーブルとしてのちに条件にあった値を抽出したいと考えています。
01294941

2021/11/27 14:26

嬉しいことに皆様に複数の解答を得られたので全て確認させていただきたいと思っています。
melian

2021/11/28 00:06

> テキストファイル自体はモデルを複数回回してその結果を出力したものです。 出力データを整形するのではなく、その出力ルーチン自体を修正する方が良いのではないでしょうか。
guest

回答4

0

タイトルにある

csvファイル

とは、スペースをデリミタとした character-separated values をデータ行とするファイルという意味と解釈しました。

とりあえず、半角スペース1個をデリミタとするCSV(Character Separated Value)ファイルをoutputB.csvとして作るには、以下でよいかと。
(※ファイルをオープンできない場合のエラー対応は省略しています)

python3

1f_in = open('outputA.txt') 2f_out = open('outputB.csv', 'w') 3 4csv = [] 5line_counter = 0 6 7for line in f_in: 8 if line_counter == 0: 9 f_out.write(line) 10 else: 11 csv.append(line.strip()) 12 if line_counter % 4 == 0: 13 f_out.write(' '.join(csv)) 14 f_out.write('\n') 15 csv = [] 16 line_counter += 1 17 18 19f_out.close() 20f_in.close()

備考1

何らかのドキュメントの中で、そのドキュメントの文脈の中でCSV とは、区切りをカンマに限定せず、何らかのデリミタ文字による区切りのほうの Character Separated Value を表しているということを明記しているものの例を探すと、以下のようなものがありました。

ただし、一般的には CSV と言われると、デリミタについて特に何の言及もない場合は、デリミタはカンマであると想定する、すなわちCSVのCは、Commmaの略であることを暗黙の了解とするのが通例です。

備考2

tatsu4941さんへ

  • 質問のタイトルが、「テキストファイルをcsvファイルに変換したい」というものだったので、上記の回答は 質問のタイトルどおり、(デリミタがカンマ以外もあり得るという意味で広義の)CSVファイルを出力することを最優先にしています。

  • デリミタをスペース1個にしたのは、入力ファイルのデータ行に 10 300.031592 0.047514 といった、スペース1個区切りの行が元からあるので、これを踏襲したものです。

  • ちなみに上記で回答したコードによって出力された、スペース1個区切りのCSVファイルoutputB.csvを質問にあるような、各列を何らかの桁数で揃えたテキストを得るのは、プログラムを書かなくても awk というコマンドを使えばできます。

shell

1$ awk '{printf "%2s %2s %-2s %-8s %-8s %-8s\n", $1, $2, $3, $4, $5, $6}' outputB.csv | head -5 2SZ VZ VA LAD BRF_toc BRF_toa 310 30 0 0.004976 0.076048 0.080558 410 30 0 0.04976 0.071202 0.075713 510 30 0 0.2488 0.057755 0.066864 610 30 0 0.4976 0.046093 0.058653

awkも便利なのでちょっとお調べになってみるとよいかもしれません。

備考3

質問にある google drive にあるファイルをダウンロードして outputA.txt というファイルに保存してテキストエディタ(vi)で開いてみると、以下のようになっています。

イメージ説明

これを見るに、^M\r(キャリッジリターン)ですので、元々、outputA.txt はスペース1個をデリミタとするCSVにしようとして、し損なっているかのようにも思えました。とまれ、現状は上記のようになっているので、\r を削除すれば、スペース1個区切りのCSVになります。それには、Pythonでプログラムを書かなくても sedコマンドで可能です。

shell

1$ sed -e "s/\r//g" outputA.txt | head -5 2SZ VZ VA LAD BRF_toc BRF_toa 310 30 0 0.004976 0.076048 0.080558 410 30 0 0.04976 0.071202 0.075713 510 30 0 0.2488 0.057755 0.066864 610 30 0 0.4976 0.046093 0.058653

または、先ほどのawkを使って桁をそろえると、以下のようになります。

shell

1$ sed -e "s/\r//g" outputA.txt | awk '{printf "%2s %2s %-2s %-8s %-8s %-8s\n", $1, $2, $3, $4, $5, $6}' | head -5 2SZ VZ VA LAD BRF_toc BRF_toa 310 30 0 0.004976 0.076048 0.080558 410 30 0 0.04976 0.071202 0.075713 510 30 0 0.2488 0.057755 0.066864 610 30 0 0.4976 0.046093 0.058653

投稿2021/11/27 04:49

編集2021/11/27 08:30
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Zuishin

2021/11/27 04:58

質問の例を見る限り、どう見ても空白一つではありません。 タブでもないですね。 複数のスペースで列揃えをしているように見えます。 データを全部舐めた上で列のサイズを定めるか、または各列のサイズをあらかじめ指定する必要がありそうです。 また、元データにデリミタのある行とない行が存在します。 ここも調整が必要でしょう。
Zuishin

2021/11/27 05:20

高評価されたようなので、低評価で 0 に戻します。 この回答は CSV について述べたものですが、質問は現状公開されている情報のみから判断して、固定長フォーマットに見えます。
01294941

2021/11/28 15:33

kilesa様 私のつたない説明にもとても細かく説明を載せてくださりありがとうございます。 非常に参考にさせていただきます。
guest

0

UNIX tools には column というコマンドがありまして、、

bash

1$ tr -d '\r' < outputA.txt | column -t > output.txt 2$ wc -l output.txt 34841 output.txt 4$ head output.txt 5SZ VZ VA LAD BRF_toc BRF_toa 610 30 0 0.004976 0.076048 0.080558 710 30 0 0.04976 0.071202 0.075713 810 30 0 0.2488 0.057755 0.066864 910 30 0 0.4976 0.046093 0.058653 1010 30 0 0.9952 0.034163 0.049216 1110 30 0 1.4928 0.026823 0.044030 1210 30 0 1.9904 0.022056 0.039995 1310 30 0 2.488 0.019717 0.038485 1410 30 0 2.9856 0.017362 0.037714 15 16# 欠損値の有無をチェック 17$ awk '{print NF}' output.txt | uniq 186

投稿2021/11/27 07:45

編集2021/11/27 07:55
melian

総合スコア20655

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

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

01294941

2021/11/28 16:11

melian様 ありがとうございます。 columnコマンド参考にさせていただきます。 またもとのルーチンも見直してみようと思います。 また何かありましたらアドバイスいただけると幸いです。
guest

0

ベストアンサー

ExcelVBAでよければ置いときます。

VBA

1Option Explicit 2Sub sample() 3 4 Dim ws As Worksheet 5 Set ws = ActiveSheet 6 7 Dim fso 'As Scripting.FileSystemObject 8 Set fso = CreateObject("Scripting.FileSystemObject") 9 10 Dim all 11 all = fso.OpenTextFile("C:\outputA.txt").ReadAll 12 13 Dim lines, head, cmax 14 lines = Split(all, vbLf) 15 head = Split(lines(0)) 16 cmax = UBound(head) 17 ws.Rows(1).Resize(, cmax + 1).Value = head 18 19 Dim i, e 20 Dim dic As Scripting.Dictionary 21 Set dic = CreateObject("Scripting.Dictionary") 22 23 For i = 1 To UBound(lines) 24 For Each e In Split(lines(i)) 25 If e <> "" Then dic.Add dic.Count, e 26 DoEvents 27 Next 28 Next 29 30 ReDim data(1 To dic.Count / (cmax + 1), 1 To cmax + 1) 31 32 Dim r, c 33 r = 1 34 For Each e In dic.Items 35 c = c + 1 36 data(r, c) = e 37 If c > cmax Then 38 c = 0 39 r = r + 1 40 End If 41 DoEvents 42 Next 43 44 ws.Range("A2").Resize(UBound(data, 1), UBound(data, 2)).Value = data 45 46 47End Sub 48

投稿2021/11/27 04:59

jinoji

総合スコア4592

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

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

01294941

2021/12/01 17:29

jinoli様 ありがとうございました。コピペさせて頂きました。 ExcelVBAなんて使ったことなかったのですが、使える人がやるとこんなに便利なのかと感動しました。 また何かあったら教えていただけると幸いです。
guest

0

Python

1import csv 2 3def special_read(fname): 4 """ 最初の行のアイテム数に合わせて読み込む """ 5 with open(fname, 'r', newline='', encoding='shift_jis') as fo: 6 reader = csv.reader(fo, delimiter=' ') 7 lst = [[item for item in row if item]for row in reader] 8 k, sz = 1, len(lst[0]) 9 lst2 = [(k:=i+1) and sum(lst[j:i+1], []) 10 for i in range(1, len(lst)) 11 if sum(map(len, lst[k:i+1])) == sz and (j:=k)+1] 12 return [lst[0]] + lst2 13 14def write_ssv(fname, lst): 15 with open(fname, 'w', newline='', encoding='shift_jis') as fo: 16 writer = csv.writer(fo, delimiter=' ') 17 writer.writerows(lst) 18 19def write_by_format(fname, lst, form): 20 with open(fname, 'w', newline='', encoding='shift_jis') as fo: 21 cont = [' '.join(f'{s:{abs(form[i])}}' if form[i] < 0 else f'{s:>{form[i]}}' 22 for i,s in enumerate(ls))+'\n' for ls in lst] 23 fo.writelines(cont) 24 25# 最初の行のアイテム数に合わせてリストに読み込む 26lst = special_read('outputA.txt') 27# 単に半角スペース区切りで 'outputB.txt' に出力 28write_ssv('outputB.txt', lst) 29# フィールド幅を指定(負の値は左寄せ)して 'outputC.txt' に出力 30write_by_format('outputC.txt', lst, [2, 2, 3, -8, -8, -8]) 31

投稿2021/11/27 08:45

lehshell

総合スコア1156

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問