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

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

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

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

Q&A

3回答

1244閲覧

テキストファイル内の指定した文字を行ごと消したいです

L.K

総合スコア0

Python

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

0グッド

0クリップ

投稿2021/06/16 15:17

前提・実現したいこと

python初心者です.
フォルダ内の全テキストファイルに対し,指定した文字を含む行をすべて削除したいです.
テキストファイル内部は,
2g-3950cc 5c -81 2437
2g-3950ed bc -76 2442

と,このように文字列と数字が混在しています.
この一番左側の(例えば2g-3950cc)文字列を指定することでその行自体が削除されるようにしたいです.

発生している問題・エラーメッセージ

'list' object has no attribute 'split'

該当のソースコード

import os filepath1 = 'テキストファイルが保存されているフォルダのパス' textname1 = os.listdir(filepath1) namelen1 = len(textname1) lines=[] for i in range(namelen1):#テキストファイルの読み込み with open(filepath1+textname1[i],'r',encoding='utf-8') as f: lines = f.readlines() with open(filepath1+textname1[i],'w',encoding='utf-8') as f: for line in lines: a, _, _, _ = lines.split("\t") if not str(a)=='2g-3950cc': f.writeline()

試したこと

リストではsplitが使えないということなのかと調べましたが,splitが使えるときと使えないときの違いがよく分かりません....
初心者質問で申し訳ありませんが,ご教授お願い致します。

補足情報(FW/ツールのバージョンなど)

詳しいバージョンはどこを確認すればいいか分かりませんでした.
spyderを利用しています.

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

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

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

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

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

kazuma-s

2021/06/16 23:54

入力ファイルや検索文字列の仕様を明確にしてください。 文字列は、1個のタブだけで区切られているのか? すべての行に 4個ずつ文字列があるのか? 検索文字列は、先頭の物だけか?
L.K

2021/06/17 06:02

ご指摘ありがとうございます. 入力するテキストファイルの仕様としては, 文字列は1個のタブだけで区切られている(全ての行において) 全ての行に4個の文字列 検索文字列は先頭のものだけ です.よろしくお願い致します.
guest

回答3

0

入力するテキストファイルの仕様としては,

文字列は1個のタブだけで区切られている(全ての行において)
全ての行に4個の文字列
検索文字列は先頭のものだけ
です.よろしくお願い致します.

ということは空行はないのですね。

Python

1import os 2 3filepath1 = 'テキストファイルが保存されているフォルダのパス/' 4 5for name in os.listdir(filepath1): 6 with open(filepath1 + name, 'r', encoding='utf-8') as f: 7 lines = f.readlines() 8 9 with open(filepath1 + name, 'w', encoding='utf-8') as f: 10 for line in lines: 11 if not line.startswith('2g-3950cc\t'): 12 f.write(line)

投稿2021/06/17 12:33

kazuma-s

総合スコア8224

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

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

0

リストではsplitが使えないということなのかと調べましたが,

その通りです。
splitは文字列に対して使います。

Python

1 for line in lines: 2 a, _, _, _ = lines.split("\t")

は、おそらくlineと書くべき所をlinesとタイプミスをしてしまって、エラーが出ているのにその間違いに気づいてないと言うことだと思ったのですが、

リストではsplitが使えないということなのかと調べましたが,

みたいなことを書いているということは、リストのままで処理しようとしているということであれば、単純なタイプミスでは無いのかも知れません。

投稿2021/06/16 15:35

otn

総合スコア85778

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

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

L.K

2021/06/16 18:35

詳しいご回答ありがとうございます。 lineとlinesがごちゃごちゃになっていました. おかげさまで整理でき,エラーメッセージも消えました.ありがとうございます。もう少し伺いたいのですが, for i in range(namelen1):#テキストファイルの読み込み with open(filepath1+textname1[i],'r',encoding='utf-8') as f: lines = f.readlines() for line in lines: a,_,_,_=line.split("\t") with open(filepath1+textname1[i],'w',encoding='utf-8') as f: if a !='2g-3950cc': f.write(line) と書き換えたところ,今度はa,_,_,_=line.split("\t")のところで not enough values to unpack (expected 4, got 1) というエラーメッセージが出ました.print(a)でどこまで抽出できているのか確認したところ,全ての単語が抽出できていました.最後の行が空白だからエラーメッセージが出るのでしょうか.全行分の単語は抽出できているが,最後にエラーが出るため次のファイルの読み込みができない状態です. また,ファイルの書き換がうまくいっているかテキストファイルの中身を確認したところ,'2g-3950cc'が含まれた行を消したいのにその行だけでなく,最後以外の行がすべて消えてしまっています.これは単語の指定の仕方,中身の書き換えのコードがまずいのでしょうか? 何度も申し訳ございません。ご教授いただければ幸いです。
otn

2021/06/17 00:32

> 最後の行が空白だからエラーメッセージが出るのでしょうか. そうですね。そのプログラムだと、「タブ区切りで4カラムであるデータ」以外があるとエラーになります。 タブの無い空行だと当然エラーですね。 x = line.split("\t") して、len(x)が4であることを確認すれば良いのでは? > 最後以外の行がすべて消えてしまっています. 各行を毎回ファイルに上書きしているので、最後にopenして書いた物以外は上書きされます。 質問文のコードだとちゃんと出来ているのになぜそんな書き換えをしてしまったんでしょうか。
guest

0

実行はできてないですけど
こうじゃないですかね。

diff

1import os 2filepath1 = 'テキストファイルが保存されているフォルダのパス' 3textname1 = os.listdir(filepath1) 4namelen1 = len(textname1) 5lines=[] 6for i in range(namelen1):#テキストファイルの読み込み 7 with open(filepath1+textname1[i],'r',encoding='utf-8') as f: 8 lines = f.readlines() 9 10 with open(filepath1+textname1[i],'w',encoding='utf-8') as f: 11 for line in lines: 12+ try:    # コメントの依頼より。 13- a, _, _, _ = lines.split("\t") 14+ a, _, _, _ = line.split("\t") 15+ except ValueError: 16+ continue 17 18 if not str(a)=='2g-3950cc': 19 f.writeline()

[splitが使えるときと使えないときの違いがよく分かりません....]
に関してですが、
splitは文字列に対して使います。

line="hogehoge@fugagufa" line.split("@") >>> ["hogehoge","fugafuga"]

というようにsplitに指定した引数で文字列を分割してリストにします。

基本的に文字列じゃないものにsplitは使えません。

上のコードだと、linesは文字列ではなくリストなので、splitは使えません

lines=["hoge@hoge","fuga@fuga"] lines.split("@")  # これはエラーになる

あと別件ですけどここも気になりました。

a,_,_ ,_ = line.split("\t")

全ての行がタブで4つ区切られてるなら構いませんが、そうでない場合エラーで止まります。
先頭の単語だけ得るなら

s = line.split("\t") a = s[0]

の方がより汎用的に使用できるんじゃないですかね。

(2番目、3番目も取得したいなら

s = line.split("\t") a1 = s[0] # 1番目 if len(s) > 2: # 分割後のリストの長さが2より大きいか調べる。これをしないと、1つしか単語がないのにs[1]等とするとValueErrorが起きるため。 a2 = s[1] # 2番目 a3 = s[2] # 3番目

とします)

投稿2021/06/16 15:27

編集2021/06/16 23:41
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

L.K

2021/06/16 18:17

詳しいご回答ありがとうございます。 line.splitで'list' object has no attribute 'split'のエラーメッセージは消えました. また,先頭の単語だけ区切った方が良いのではないかというご指摘もありがとうございます.その通りなのですが,今後2つ目や3つ目の単語も抽出したいのでとりあえずはこのままでお付き合いいただけたら幸いです. 当初のエラーメッセージは消えたのですが,最後の行がタブで4つに区切られていないからか not enough values to unpack (expected 4, got 1) というエラーメッセージが出ました(ご指摘された通りで申し訳ないです).printで確認したところ,単語は全て抽出できているのですが,最後の空行のせいでなのか,ループが止まり,次のテキストファイルを読み込めない状況です.この場合の解決策をご教授いただけますでしょうか。
退会済みユーザー

退会済みユーザー

2021/06/16 23:38 編集

空行のため4つに分割できず「not enough values to unpack (expected 4, got 1)」のエラーになっているということですね あまりいいやり方じゃないかもしれませんが、try/exceptを使って、not enough values to unpack が発生したときは無視する形に修正しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問