একটি ফাইলের একটি নির্দিষ্ট লাইন মুছে ফেলার জন্য পাইথন ব্যবহার করে


145

আসুন ধরা যাক আমার কাছে ডাক নামগুলি পূর্ণ একটি টেক্সট ফাইল রয়েছে। পাইথন ব্যবহার করে কীভাবে আমি এই ফাইল থেকে একটি নির্দিষ্ট ডাকনাম মুছতে পারি?


1
fileinput@ Jf-sebastian এখানে বর্ণিত হিসাবে চেষ্টা করুন । মনে হচ্ছে আপনাকে অস্থায়ী ফাইলের মাধ্যমে লাইন-বাই-লাইনে কাজ করার অনুমতি দেওয়া হয়েছে, forসবগুলিই একটি সাধারণ সিনট্যাক্স সহ।
কেভিন

উত্তর:


205

প্রথমে ফাইলটি খুলুন এবং ফাইলটি থেকে আপনার সমস্ত লাইন পান। তারপরে রাইট মোডে ফাইলটি আবার খুলুন এবং আপনি যে লাইনটি মুছতে চান সেগুলি বাদ দিয়ে আপনার লাইনগুলি আবার লিখুন:

with open("yourfile.txt", "r") as f:
    lines = f.readlines()
with open("yourfile.txt", "w") as f:
    for line in lines:
        if line.strip("\n") != "nickname_to_delete":
            f.write(line)

strip("\n")তুলনার ক্ষেত্রে আপনাকে নিউলাইন চরিত্রের প্রয়োজন কারণ যদি আপনার ফাইলটি একটি নিউলাইন চরিত্রের সাথে শেষ lineনা হয় তবে শেষটি আর হয় না।


2
কেন আমরা এটি দুটি বার খুলতে এবং বন্ধ করতে হবে?
ওকার

3
@ ওকার: আপনাকে ফাইলটি দু'বার খুলতে হবে (এবং এর মধ্যে এটি বন্ধ করতে হবে) কারণ প্রথম মোডে এটি "কেবল পঠনযোগ্য" কারণ আপনি কেবল ফাইলের বর্তমান লাইনেই পড়ছেন। তারপরে আপনি এটিটি বন্ধ করে "লিখন মোডে" পুনরায় খুলুন, যেখানে ফাইলটি লেখার যোগ্য এবং আপনি ফাইলটির সামগ্রীগুলি যে রেখাটি সরাতে চেয়েছিলেন সেটি সরিয়ে দেয়।
ডেভিন

4
পাইথন কেন আমাদের এক লাইনে এটি করতে দেয় না?
ওকার

5
@ ওকার, আপনি যখন একটি লাইন পড়েন, লাইনটি পড়ার সাথে সাথে কার্সারটি চলার কল্পনা করার চেষ্টা করুন। একবার লাইনটি পড়ার পরে কার্সারটি এখন অতীত। আপনি যখন ফাইলটিতে লেখার চেষ্টা করবেন তখন লিখবেন যেখানে কার্সার বর্তমানে রয়েছে। ফাইলটি পুনরায় খোলার মাধ্যমে আপনি কার্সারটিকে পুনরায় সেট করুন।
ওয়াদ্দাস

4
যৌগের সাথে ব্যবহার করুন!
সিস্লুসওয়ে

100

শুধুমাত্র একটি একক উন্মুক্ত সাহায্যে এই সমস্যার সমাধান:

with open("target.txt", "r+") as f:
    d = f.readlines()
    f.seek(0)
    for i in d:
        if i != "line you want to remove...":
            f.write(i)
    f.truncate()

এই সমাধানটি ফাইলটি আর / ডাব্লু মোডে খোলে ("আর +") এবং এফ-পয়েন্টারটি পুনরায় সেট করার চেষ্টা করে তারপরে শেষ লেখার পরে সমস্ত কিছু সরিয়ে ফেলতে কাটছাঁট করে।


2
এটি আমার পক্ষে খুব ভাল কাজ করেছে, কারণ আমাকে লকফিলও ব্যবহার করতে হয়েছিল (fcntl)। আমি এফসিএনটিএল এর সাথে একসাথে ফাইল ইনপুট ব্যবহারের কোনও উপায় খুঁজে পাই না।
Easyrider 27'15

1
এই সমাধানটির কিছু পার্শ্ব প্রতিক্রিয়া দেখে ভাল লাগবে।
ব্যবহারকারী 1767754

3
আমি এই কাজ না। আপনি যদি forলুপটিতে ত্রুটি পান তবে আপনার ডুপ্লিকেট লাইন বা একটি অর্ধেক কাটা কাটা আংশিক ওভাররাইট ফাইল দিয়ে শেষ হবে। পরিবর্তে আপনি f.truncate()ডান চাইতে পারেন f.seek(0)। যদি আপনি কোনও ত্রুটি পান তবে আপনি কেবল একটি অসম্পূর্ণ ফাইলটি শেষ করবেন। তবে আসল সমাধানটি (যদি আপনার কাছে ডিস্কের স্থান থাকে) হ'ল কোনও অস্থায়ী ফাইলে আউটপুট আনা এবং তারপরে সমস্ত কিছু সাফল্যের পরে এটি ব্যবহার করে os.replace()বা pathlib.Path(temp_filename).replace(original_filename)মূলটির সাথে অদলবদল করা।
বরিস

আপনি i.strip('\n') != "line you want to remove..."গ্রহণযোগ্য উত্তরে উল্লিখিত হিসাবে যুক্ত করতে পারেন , এটি আমার সমস্যার পুরোপুরি সমাধান করবে। কারণ শুধু iআমার জন্য কিছুই করেনি
ম্যাঙ্গোহেরো 1

31

একটি তালিকাতে সমস্ত কিছু সংরক্ষণ এবং ফাইলটি লেখার জন্য পুনরায় খোলার চেয়ে সেরা এবং দ্রুত বিকল্পটি আমার মতে ফাইলটি অন্য কোথাও পুনরায় লেখার পক্ষে।

with open("yourfile.txt", "r") as input:
    with open("newfile.txt", "w") as output: 
        for line in input:
            if line.strip("\n") != "nickname_to_delete":
                output.write(line)

এটাই! একটি লুপ এবং একটিতে আপনি একই জিনিস করতে পারেন। এটি আরও দ্রুত হবে।


লুপের জন্য সাধারণ ব্যবহার না করে আমরা জেনারেটর এক্সপ্রেশন ব্যবহার করতে পারি এইভাবে প্রোগ্রামটি ফাইল থেকে মেমরির সমস্ত লাইন লোড করবে না যা বড় ফাইলগুলির ক্ষেত্রে ভাল ধারণা নয়। এটিতে কেবল একবারে স্মৃতিতে একক লাইন থাকবে। লুপের জন্য জেনারেটর এক্সপ্রেশন সহ দেখতে হবে,(output.write(line) for line in input if line!="nickname_to_delete"+"\n")
শ্রীশিন্দে

4
@ শ্রীশিন্দে আপনি যখন ফাইলের বস্তুটি লুপ করবেন তখন আপনি মেমোরিতে ফাইলটি পড়ছেন না, সুতরাং এই সমাধানটি আপনার পরামর্শের মতোই কাজ করে।
স্টেইনার লিমা

আপনি মূল ফাইলটি মুছতে এবং দ্বিতীয় ফাইলটির মূল ফাইলটির নাম পরিবর্তন করতে চাইতে পারেন, যা লিনাক্স ওএসে পাইথন সহ এইরকম দেখাবেsubprocess.call(['mv', 'newfile.txt', 'yourfile.txt'])
ম্যাক্স

6
os.replace(পাইথন ভি ৩.৩ এ নতুন) সিস্টেম কল করার চেয়ে ক্রস প্ল্যাটফর্ম mv
7yl4r

সহজ এবং দুর্দান্ত।
জুবায়ের AD

27

এটি @ অন্যের উত্তর থেকে একটি "কাঁটাচামচ" (যা আমি বিশ্বাস করি যে সঠিক উত্তর হিসাবে বিবেচনা করা উচিত)।


এই জাতীয় একটি ফাইলের জন্য:

$ cat file.txt 
1: october rust
2: november rain
3: december snow

লথারের সমাধান থেকে এই কাঁটাটি ভাল কাজ করে:

#!/usr/bin/python3.4

with open("file.txt","r+") as f:
    new_f = f.readlines()
    f.seek(0)
    for line in new_f:
        if "snow" not in line:
            f.write(line)
    f.truncate()

উন্নতি:

  • with open, যা ব্যবহার বাতিল করে দেয় f.close()
  • if/elseস্ট্রিংটি বর্তমান লাইনে উপস্থিত না থাকলে মূল্যায়নের জন্য আরও পরিষ্কার

যদি f.seek (0) প্রয়োজন?
yifan

@ আইফান হ্যাঁ অন্যথায় ফাইলটি ওভাররাইট করার পরিবর্তে আপনি নিজেই ফাইলটি যুক্ত করবেন (আপনি যে লাইনগুলি বাদ দিচ্ছেন না)।
বোরিস

5

প্রথম পাসে লাইনগুলি পড়ার এবং দ্বিতীয় পাসে পরিবর্তনগুলি (নির্দিষ্ট লাইনগুলি মুছে ফেলার) সাথে সমস্যাটি হ'ল যদি আপনি আকারগুলি ফাইল করেন তবে আপনি র‍্যামের বাইরে চলে যাবেন। পরিবর্তে, আরও ভাল পদ্ধতি হ'ল একে একে লাইনগুলি পড়ুন এবং সেগুলি আপনার প্রয়োজন হয় না সেগুলি সরিয়ে একটি পৃথক ফাইলে লিখুন। আমি 12-50 গিগাবাইটের মতো বড় ফাইলগুলির সাথে এই পদ্ধতির চালনা করেছি এবং র‌্যামের ব্যবহার প্রায় স্থির থাকে। কেবল সিপিইউ চক্র প্রক্রিয়াধীন অবস্থায় দেখায়।


2

এই উত্তরে বর্ণিত হিসাবে ফাইলিনপুট পদ্ধতিটি আমি পছন্দ করেছি: একটি পাঠ্য ফাইল (পাইথন) থেকে একটি লাইন মুছে ফেলা

উদাহরণস্বরূপ বলুন আমার কাছে একটি ফাইল রয়েছে যার এতে ফাঁকা লাইন রয়েছে এবং আমি খালি লাইনগুলি মুছে ফেলতে চাই, আমি এখানে এটি কীভাবে সমাধান করেছি:

import fileinput
import sys
for line_number, line in enumerate(fileinput.input('file1.txt', inplace=1)):
    if len(line) > 1:
            sys.stdout.write(line)

দ্রষ্টব্য: আমার ক্ষেত্রে খালি লাইনগুলির দৈর্ঘ্য 1 ছিল


2

আপনি যদি লিনাক্স ব্যবহার করেন তবে আপনি নিম্নলিখিত পদ্ধতির চেষ্টা করতে পারেন।
ধরা যাক আপনার নামের একটি পাঠ্য ফাইল রয়েছে animal.txt:

$ cat animal.txt  
dog
pig
cat 
monkey         
elephant  

প্রথম লাইনটি মুছুন:

>>> import subprocess
>>> subprocess.call(['sed','-i','/.*dog.*/d','animal.txt']) 

তারপর

$ cat animal.txt
pig
cat
monkey
elephant

7
এই সমাধানটি ওএস অজানাস্টিক নয়, এবং যেহেতু ওপি কোনও অপারেশন সিস্টেম নির্দিষ্ট করে নি, তাই লিনাক্সের নির্দিষ্ট উত্তর ইমো পোস্ট করার কোনও কারণ নেই।
স্টেইনার লিমা

2
যে কেউ যে কেবল অজগর দিয়ে করা যায় এমন যে কোনও কিছুর জন্য সাবপ্রসেস ব্যবহার করার পরামর্শ দেয় সে ডাউনটওয়েট পায়! এবং +1 থেকে @ স্টেইনারলিমা ... আমি সম্মত
জেমি লিন্ডসে

2

আমি মনে করি আপনি যদি ফাইলটিকে একটি তালিকার মধ্যে পড়ে থাকেন তবে আপনি যে নামটি থেকে মুক্তি পেতে চান তার সন্ধানের জন্য তালিকার উপরে পুনরাবৃত্তি করতে পারেন। আপনি অতিরিক্ত ফাইল তৈরি না করে এটি বেশ দক্ষতার সাথে করতে পারেন, তবে আপনাকে ফলাফলটি সোর্স ফাইলে আবার লিখতে হবে।

আমি এখানে এটি কীভাবে করতে পারি তা এখানে:

import, os, csv # and other imports you need
nicknames_to_delete = ['Nick', 'Stephen', 'Mark']

আমি ধরে নিচ্ছি যে এই জাতীয় nicknames.csvডেটা রয়েছে:

Nick
Maria
James
Chris
Mario
Stephen
Isabella
Ahmed
Julia
Mark
...

তারপরে তালিকায় ফাইলটি লোড করুন:

 nicknames = None
 with open("nicknames.csv") as sourceFile:
     nicknames = sourceFile.read().splitlines()

এরপরে, মুছে ফেলার জন্য আপনার ইনপুটগুলির সাথে মেলে তালিকাতে পুনরাবৃত্তি করুন:

for nick in nicknames_to_delete:
     try:
         if nick in nicknames:
             nicknames.pop(nicknames.index(nick))
         else:
             print(nick + " is not found in the file")
     except ValueError:
         pass

শেষ পর্যন্ত, ফলাফলটি ফাইলটিতে ফিরে লিখুন:

with open("nicknames.csv", "a") as nicknamesFile:
    nicknamesFile.seek(0)
    nicknamesFile.truncate()
    nicknamesWriter = csv.writer(nicknamesFile)
    for name in nicknames:
        nicknamesWriter.writeRow([str(name)])
nicknamesFile.close()

1

সাধারণভাবে, আপনি পারবেন না; আপনাকে পুরো ফাইলটি আবার লিখতে হবে (কমপক্ষে পরিবর্তনের দিক থেকে শেষ অবধি)।

কিছু নির্দিষ্ট ক্ষেত্রে আপনি এর থেকে আরও ভাল করতে পারেন -

যদি আপনার সমস্ত ডেটা উপাদানগুলি একই দৈর্ঘ্য এবং কোনও নির্দিষ্ট ক্রমে না থাকে এবং আপনি যেটি থেকে মুক্তি পেতে চান তার অফসেটটি জানেন, আপনি মুছে ফেলার জন্য শেষ আইটেমটি অনুলিপি করতে পারবেন এবং শেষ আইটেমের আগে ফাইলটি কেটে ফেলতে পারবেন ;

অথবা আপনি কেবলমাত্র 'এটি খারাপ ডেটা, এটি এড়িয়ে যান' মান দিয়ে বা সংরক্ষণিত ডেটা উপাদানগুলিতে একটি 'এই আইটেমটি মুছে ফেলা হয়েছে' রেখে পতাকাটি মুছে ফেলতে পারেন যেমন আপনি অন্যথায় ফাইলটি পরিবর্তন না করে মুছে ফেলাতে চিহ্নিত করতে পারেন।

এটি সম্ভবত সংক্ষিপ্ত দলিলগুলির জন্য ওভারকিল (100 কেবি এর নীচে কিছু?)


1

সম্ভবত, আপনি ইতিমধ্যে একটি সঠিক উত্তর পেয়েছেন, তবে এখানে আমার। আনফিল্টারড ডেটা সংগ্রহ করার জন্য একটি তালিকা ব্যবহার না করে (কী readlines()পদ্ধতিটি ব্যবহার করে), আমি দুটি ফাইল ব্যবহার করি। একটি হ'ল একটি প্রধান ডেটা ধরে রাখার জন্য এবং দ্বিতীয়টি হ'ল ডেটা ফিল্টার করার জন্য যখন আপনি একটি নির্দিষ্ট স্ট্রিং মুছবেন। এখানে একটি কোড:

main_file = open('data_base.txt').read()    # your main dataBase file
filter_file = open('filter_base.txt', 'w')
filter_file.write(main_file)
filter_file.close()
main_file = open('data_base.txt', 'w')
for line in open('filter_base'):
    if 'your data to delete' not in line:    # remove a specific string
        main_file.write(line)                # put all strings back to your db except deleted
    else: pass
main_file.close()

আশা করি আপনি এটি দরকারী পাবেন! :)


0

একটি তালিকার মধ্যে ফাইল লাইনগুলি সংরক্ষণ করুন, তারপরে তালিকাটি মুছে ফেলুন এবং আপনি মুছে ফেলতে চান এমন লাইনটি একটি নতুন ফাইলটিতে লিখুন

with open("file_name.txt", "r") as f:
    lines = f.readlines() 
    lines.remove("Line you want to delete\n")
    with open("new_file.txt", "w") as new_f:
        for line in lines:        
            new_f.write(line)

উত্তর দেওয়ার সময় আপনার উত্তরটি হ'ল কেন তা সম্পর্কে কিছুটা ব্যাখ্যা দেওয়া ভাল ।
স্টিফেন রাউচ

যদি আপনার ফাইলটি কোনও নতুন লাইনের সাথে শেষ না হয় তবে এই কোডটি সর্বশেষ লাইনটি সরিয়ে ফেলবে না যদিও এতে আপনি মুছে ফেলতে চান এমন কোনও শব্দ রয়েছে।
বরিস

0

একটি ফাইল থেকে একটি / কিছু লাইন (গুলি) অপসারণের জন্য এখানে অন্য কিছু পদ্ধতি রয়েছে:

src_file = zzzz.txt
f = open(src_file, "r")
contents = f.readlines()
f.close()

contents.pop(idx) # remove the line item from list, by line number, starts from 0

f = open(src_file, "w")
contents = "".join(contents)
f.write(contents)
f.close()

0

আমি এই পদ্ধতিটি ফাইল ইনপুট এবং 'অন্তর্নিহিত' পদ্ধতিটি ব্যবহার করে পছন্দ করি:

import fileinput
for line in fileinput.input(fname, inplace =1):
    line = line.strip()
    if not 'UnwantedWord' in line:
        print(line)

এটি অন্যান্য উত্তরের তুলনায় কিছুটা কম শব্দযুক্ত এবং এর জন্য দ্রুত যথেষ্ট


0

আপনি reগ্রন্থাগারটি ব্যবহার করতে পারেন

ধরে নিচ্ছি যে আপনি আপনার সম্পূর্ণ টিএসটি-ফাইল লোড করতে সক্ষম। তারপরে আপনি অযাচিত ডাকনামগুলির একটি তালিকা সংজ্ঞায়িত করুন এবং তারপরে খালি স্ট্রিং দিয়ে এটিকে প্রতিস্থাপন করুন।

# Delete unwanted characters
import re

# Read, then decode for py2 compat.
path_to_file = 'data/nicknames.txt'
text = open(path_to_file, 'rb').read().decode(encoding='utf-8')

# Define unwanted nicknames and substitute them
unwanted_nickname_list = ['SourDough']
text = re.sub("|".join(unwanted_nickname_list), "", text)

-1

ফাইলের নির্দিষ্ট লাইনটি তার লাইন নম্বর দ্বারা মুছতে :

আপনার ফাইলের নাম এবং আপনি মুছতে চান এমন লাইন নম্বর সহ ভেরিয়েবল ফাইলের নাম এবং লাইন_ টু_ডিলেটগুলি প্রতিস্থাপন করুন ।

filename = 'foo.txt'
line_to_delete = 3
initial_line = 1
file_lines = {}

with open(filename) as f:
    content = f.readlines() 

for line in content:
    file_lines[initial_line] = line.strip()
    initial_line += 1

f = open(filename, "w")
for line_number, line_content in file_lines.items():
    if line_number != line_to_delete:
        f.write('{}\n'.format(line_content))

f.close()
print('Deleted line: {}'.format(line_to_delete))

উদাহরণ আউটপুট :

Deleted line: 3

ডিক তৈরির দরকার নেই, কেবল ব্যবহার করুনfor nb, line in enumerate(f.readlines())
ডায়নিস

-3

ফাইলের বিষয়বস্তু নিন, এটিকে নতুন লাইনে একটি টিপল হিসাবে বিভক্ত করুন। তারপরে, আপনার টিপলের লাইন নম্বরটি অ্যাক্সেস করুন, আপনার ফলাফল টিপলটিতে যোগ দিন এবং ফাইলটিতে ওভাররাইট করুন।


6
(1) আপনার মানে tuple(f.read().split('\n'))?? (২) "আপনার টিপলের লাইন নম্বরটি অ্যাক্সেস করুন" এবং "আপনার ফলাফলের টিপলে যোগ দিন" বরং রহস্যজনক; প্রকৃত পাইথন কোডটি আরও বোধগম্য হতে পারে।
জন মাচিন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.