কোনও ফাইলের পাঠ্য কীভাবে সন্ধান এবং প্রতিস্থাপন করবেন?


212

পাইথন 3 ব্যবহার করে কোনও ফাইলের পাঠ্য কীভাবে সন্ধান এবং প্রতিস্থাপন করব?

আমার কোডটি এখানে:

import os
import sys
import fileinput

print ("Text to search for:")
textToSearch = input( "> " )

print ("Text to replace it with:")
textToReplace = input( "> " )

print ("File to perform Search-Replace on:")
fileToSearch  = input( "> " )
#fileToSearch = 'D:\dummy1.txt'

tempFile = open( fileToSearch, 'r+' )

for line in fileinput.input( fileToSearch ):
    if textToSearch in line :
        print('Match Found')
    else:
        print('Match Not Found!!')
    tempFile.write( line.replace( textToSearch, textToReplace ) )
tempFile.close()


input( '\n\n Press Enter to exit...' )

ইনপুট ফাইল:

hi this is abcd hi this is abcd
This is dummy text file.
This is how search and replace works abcd

আমি যখন উপরের ইনপুট ফাইলে 'abcd' দ্বারা 'ram' অনুসন্ধান এবং প্রতিস্থাপন করি তখন এটি কবজ হিসাবে কাজ করে। তবে আমি যখন এটি তদ্বিপরীত করে অর্থাৎ 'রাম' দ্বারা 'অ্যাবিসিডি' প্রতিস্থাপন করি তখন কিছু জাঙ্ক অক্ষর শেষে থাকে।

'রাম' দ্বারা 'অ্যাবিসিডি' প্রতিস্থাপন

hi this is ram hi this is ram
This is dummy text file.
This is how search and replace works rambcd

আপনি যখন "কিছু আবর্জনা অক্ষর শেষ অবধি রেখে গেছেন" বলছেন তখন আপনি কি আরও কিছু নির্দিষ্ট হতে পারেন, আপনি কী দেখেন?
বুরহান খালিদ

আমি কী পেয়েছি তা দিয়ে প্রশ্ন আপডেট করে Updated
শ্রীরাম

উত্তর:


241

fileinputইতিমধ্যে ইনপ্লেস সম্পাদনা সমর্থন করে। এটি stdoutএই ক্ষেত্রে ফাইলটিতে পুনঃনির্দেশ করে:

#!/usr/bin/env python3
import fileinput

with fileinput.FileInput(filename, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(text_to_search, replacement_text), end='')

13
end=''যুক্তি কী করার কথা?
egpbos

18
lineইতিমধ্যে একটি নতুন লাইন আছে। endডিফল্টরূপে একটি newline হয় end=''তোলে print()ফাংশন অতিরিক্ত সম্পর্কে newline প্রিন্ট না
JFS

11
ফাইলপুট ব্যবহার করবেন না! পরিবর্তে কোডটি নিজে লেখার জন্য বিবেচনা করুন। পুনঃনির্দেশ sys.stdout একটি দুর্দান্ত ধারণা নয়, বিশেষত যদি আপনি এটি চেষ্টা না করেই করেন..ফিনালি ফাইলপুট যেমন করেন। যদি কোনও ব্যতিক্রম উত্থাপিত হয়, আপনার স্টাডাউট কখনও পুনরুদ্ধার হতে পারে না।
ক্রেগড

9
@ ক্রাইগ্ডস: ভুল fileinputহাতিয়ার নয় সব কাজ ( কিছুই নয়) কিন্তু অনেক ক্ষেত্রে যেখানে এটি হয় হয় একটি বাস্তবায়ন ডান টুল যেমন, sedপাইথন মধ্যে -একটি ফিল্টার। নখ পাউন্ড করতে কোনও স্ক্রু ড্রাইভার ব্যবহার করবেন না।
jfs

5
যদি আপনি সত্যিই কোনও কারণে আপনার ফাইলে স্টাডাউটকে পুনর্নির্দেশ করতে চান তবে এটির চেয়ে ভাল করা এটির পক্ষে কঠিন নয় fileinput(মূলত, try..finallyআপনি স্ট্যাডআউটকে তার মূল মূল্যের পরে ফিরিয়ে আনেন তা নিশ্চিত করতে) এর উত্স কোডটি fileinputবেশ চোখের রক্তপাতের মতো ভয়াবহ এবং এটি হুডের নীচে সত্যই কিছু অনিরাপদ কাজ করে। আজ যদি এটি লেখা হয় তবে আমি খুব সন্দেহ করি যে এটি এটিকে stdlib এ পরিণত করত।
ক্রেগড

333

মাইকেল -৯৯৮ দ্বারা চিহ্নিত হিসাবে, আপনি আলাদা দৈর্ঘ্যের ডেটা সহ জায়গায় প্রতিস্থাপন করতে পারবেন না কারণ এটি বাকী অংশগুলি স্থানের বাইরে রাখবে। আপনি অন্য পোস্টারগুলির সাথে একমত নন যে আপনাকে একটি ফাইল থেকে পড়তে এবং অন্যটিতে লেখার পরামর্শ দিচ্ছে। পরিবর্তে, আমি মেমরিটিতে ফাইলটি পড়তাম, ডেটা ঠিক করতাম এবং তারপরে পৃথক পদক্ষেপে একই ফাইলটিতে লিখতাম।

# Read in the file
with open('file.txt', 'r') as file :
  filedata = file.read()

# Replace the target string
filedata = filedata.replace('ram', 'abcd')

# Write the file out again
with open('file.txt', 'w') as file:
  file.write(filedata)

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


5
with file = open(..):=অভিপ্রায়টি স্পষ্ট হলেও পাইথন বৈধ নয় ( )। .replace()স্ট্রিংটি সংশোধন করে না (এটি অপরিবর্তনীয়) সুতরাং আপনাকে ফেরত মানটি ব্যবহার করতে হবে। যাইহোক, বড় ফাইলগুলিকে সমর্থন করে এমন কোডগুলি আরও সহজ হতে পারে যদি না আপনি একাধিক লাইন ছড়িয়ে থাকা পাঠ্যটি সন্ধান এবং প্রতিস্থাপনের প্রয়োজন হয়।
jfs

40
আপনি একদম ঠিক বলেছেন, এবং তা - ভাবেন - এই কারণেই আপনার
নিজেরাই

19
@ জোনাসস্টাইন: না, এটি করা উচিত নয়। withবিবৃতি স্বয়ংক্রিয়ভাবে বিবৃতি ব্লক শেষে ফাইল বন্ধ করে।
জ্যাক এইডলি

2
পছন্দ করুন ব্যাখ্যা করার জন্য আপনাকে ধন্যবাদ.
জোনাস স্টেইন

4
@ জ্যাকএইডলি কারণ এটি সংক্ষিপ্ত, সহজ, সহজেই ব্যবহৃত এবং বোঝা যায় এবং একটি সত্যিকারের সমস্যাটিকে সম্বোধন করে যা অনেক লোকের (এবং সেইজন্য অনেক লোক অনুসন্ধান করে - এইভাবে আপনার উত্তরটি সন্ধান করে)।
বেন বারডেন

52

জ্যাক এইডলি যেমন পোস্ট করেছিলেন এবং জেএফ সেবাস্তিয়ান উল্লেখ করেছিলেন, এই কোডটি কার্যকর হবে না:

 # Read in the file
filedata = None
with file = open('file.txt', 'r') :
  filedata = file.read()

# Replace the target string
filedata.replace('ram', 'abcd')

# Write the file out again
with file = open('file.txt', 'w') :
  file.write(filedata)`

তবে এই কোডটি কাজ করবে (আমি এটি পরীক্ষা করেছি):

f = open(filein,'r')
filedata = f.read()
f.close()

newdata = filedata.replace("old data","new data")

f = open(fileout,'w')
f.write(newdata)
f.close()

এই পদ্ধতিটি ব্যবহার করে ফাইলিন এবং ফাইলআউট একই ফাইল হতে পারে, কারণ পাইথন ৩.৩ লেখার জন্য খোলার পরে ফাইলটি ওভাররাইট করবে।


9
আমি বিশ্বাস করি পার্থক্যটি এখানে রয়েছে: ফাইলডাটা.রেপ্লেস ('রাম', 'অ্যাবিসিডি') তুলনা: নতুনডাটা = ফাইলডাটা.রেপ্লেস ("পুরাতন ডেটা", "নতুন ডেটা") "উইথ" এর সাথে কিছুই করার নেই
ডিয়েগোম্যানাস

5
আপনি কেন withস্টেটমেন্ট সরিয়ে ফেলবেন? ২. আমার উত্তরে বর্ণিত হিসাবে, জায়গায় fileinputকাজ করতে পারে - এটি একই ফাইলে ডেটা প্রতিস্থাপন করতে পারে (এটি অভ্যন্তরীণভাবে একটি অস্থায়ী ফাইল ব্যবহার করে)। পার্থক্যটি হ'ল fileinputপুরো ফাইলটিকে মেমরিতে লোড করতে হবে না।
jfs

8
কেবল অন্যকে জ্যাক এইডলির উত্তরে পুনর্বিবেচনা করতে বাঁচানোর জন্য, এই উত্তরটির পরে এটি সংশোধন করা হয়েছে, সুতরাং এটি এখন অপ্রয়োজনীয় (এবং নীটার withব্লকগুলি হারিয়ে যাওয়ার কারণে নিকৃষ্ট )।
ক্রিস

46

আপনি এই মত প্রতিস্থাপন করতে পারেন

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
for line in f1:
    f2.write(line.replace('old_text', 'new_text'))
f1.close()
f2.close()

7

আপনি ব্যবহার করতে পারেন pathlib

from pathlib2 import Path
path = Path(file_to_search)
text = path.read_text()
text = text.replace(text_to_search, replacement_text)
path.write_text(text)

ধন্যবাদ ইউয়া উপরের সমাধানটি ভালভাবে কাজ করেছে। দ্রষ্টব্য: আপনাকে প্রথমে আপনার মূল ফাইলটির ব্যাকআপ নিতে হবে, কারণ এটি আপনার আসল ফাইলটি নিজেই প্রতিস্থাপন করে। আপনি যদি বারবার পাঠ্য প্রতিস্থাপন করতে চান তবে আপনি নীচের মত শেষ 2 টি লাইন যুক্ত করে রাখতে পারেন। পাঠ্য = পাঠ্য.সামান্য স্থান (পাঠ্য_ টু_সন্ধান, প্রতিস্থাপন_পদ্ধতি) পাথ.রাইট_টেক্সট (পাঠ্য)
নেজেস

3

একক ব্লক সহ, আপনি আপনার পাঠ্যটি সন্ধান এবং প্রতিস্থাপন করতে পারেন:

with open('file.txt','r+') as f:
    filedata = f.read()
    filedata = filedata.replace('abc','xyz')
    f.truncate(0)
    f.write(filedata)

1
আপনি seekফাইলটি লেখার আগে শুরুতে ভুলে গেছেন । truncateএটি না করে এবং সুতরাং আপনার ফাইলটিতে আবর্জনা থাকবে।
উর।

2

আপনার সমস্যা একই ফাইল থেকে পড়া এবং লেখা থেকে শুরু করে। fileToSearchলেখার জন্য না খোলার পরিবর্তে একটি আসল অস্থায়ী ফাইল খুলুন এবং তারপরে আপনার কাজ শেষ হয়ে গেলে এবং বন্ধ হয়ে যাওয়ার পরে, নতুন ফাইলটি সরানোর জন্য tempFileব্যবহার os.renameকরুন fileToSearch


1
বন্ধুত্বপূর্ণ এফওয়াইআই (উত্তরে নির্দ্বিধায় নির্দ্বিধায়): মূল কারণটি একটি ফাইলের মাঝখানে সংক্ষিপ্ত করতে সক্ষম হচ্ছে না। অর্থাৎ, আপনি যদি 5 টি অক্ষর সন্ধান করেন এবং 3 দিয়ে প্রতিস্থাপন করেন তবে অনুসন্ধান করা 5 টির প্রথম 3 অক্ষর প্রতিস্থাপন করা হবে; তবে অন্য 2 টি সরানো যাবে না, তারা কেবল সেখানেই থাকবে। অস্থায়ী ফাইল সমাধান অস্থায়ী ফাইলটিতে লেখার পরিবর্তে এগুলি ফেলে রেখে "" অবশিষ্ট "অক্ষরগুলি সরিয়ে দেয়।
michaelb958 - GoFundMonica

2

(পাইপ ইনস্টল পাইথন-ব্যবহার)

from pyutil import filereplace

filereplace("somefile.txt","abcd","ram")

দ্বিতীয় প্যারামিটার (যে জিনিসটি প্রতিস্থাপন করা হবে, উদাহরণস্বরূপ "abcd" একটি রেজেক্সও হতে পারে)
সমস্ত উপস্থিতি প্রতিস্থাপন করবে


এটির সাথে আমার কিছু খারাপ অভিজ্ঞতা হয়েছে (এটি ফাইলের শেষের দিকে কিছু অক্ষর যুক্ত করেছে), সুতরাং আমি এটি প্রস্তাব করতে পারছি না, যদিও একটি-লাইনার ভাল লাগবে।
আজরায়েল 3000

@ Azrael3000 এটি যোগ করেছেন? আমার সাথে তা ঘটেনি। আমি আপনার পক্ষে যদি গিথুব
মিস্টারএল 2

1

আমার রূপটি, পুরো ফাইলটিতে একবারে একটি শব্দ।

আমি এটি স্মৃতিতে পড়েছি।

def replace_word(infile,old_word,new_word):
    if not os.path.isfile(infile):
        print ("Error on replace_word, not a regular file: "+infile)
        sys.exit(1)

    f1=open(infile,'r').read()
    f2=open(infile,'w')
    m=f1.replace(old_word,new_word)
    f2.write(m)

0

আমি এটি করেছি:

#!/usr/bin/env python3

import fileinput
import os

Dir = input ("Source directory: ")
os.chdir(Dir)

Filelist = os.listdir()
print('File list: ',Filelist)

NomeFile = input ("Insert file name: ")

CarOr = input ("Text to search: ")

CarNew = input ("New text: ")

with fileinput.FileInput(NomeFile, inplace=True, backup='.bak') as file:
    for line in file:
        print(line.replace(CarOr, CarNew), end='')

file.close ()

দু: খিত, কিন্তু fileinput না doen কাজ inplace=Trueসঙ্গে utf-8
সার্জিও

0

আমি জয়রাম সিংয়ের পোস্টকে সামান্য পরিবর্তিত করে একটি 'প্রতিটি ঘটনাকে প্রতিস্থাপন করতে!' একটি সংখ্যার চরিত্র যা আমি প্রতিটি উদাহরণের সাথে বৃদ্ধি করতে চাই। ভেবেছিলেন এটি কারওর পক্ষে সহায়ক হতে পারে যিনি প্রতি লাইনে একবারে একাধিকবার উপস্থিত এবং পুনরাবৃত্তি করতে চান এমন একটি চরিত্র পরিবর্তন করতে চেয়েছিলেন। আশা করি যে কাউকে সাহায্য করবে। PS- আমার পোস্টটি কোনওভাবেই অনুপযুক্ত থাকলে ক্ষমা চেয়ে কোডিংয়ে আমি খুব নতুন but তবে এটি আমার পক্ষে কাজ করেছে।

f1 = open('file1.txt', 'r')
f2 = open('file2.txt', 'w')
n = 1  

# if word=='!'replace w/ [n] & increment n; else append same word to     
# file2

for line in f1:
    for word in line:
        if word == '!':
            f2.write(word.replace('!', f'[{n}]'))
            n += 1
        else:
            f2.write(word)
f1.close()
f2.close()

0
def word_replace(filename,old,new):
    c=0
    with open(filename,'r+',encoding ='utf-8') as f:
        a=f.read()
        b=a.split()
        for i in range(0,len(b)):
            if b[i]==old:
                c=c+1
        old=old.center(len(old)+2)
        new=new.center(len(new)+2)
        d=a.replace(old,new,c)
        f.truncate(0)
        f.seek(0)
        f.write(d)
    print('All words have been replaced!!!')

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

0

তাই ভালো:

def find_and_replace(file, word, replacement):
  with open(file, 'r+') as f:
    text = f.read()
    f.write(text.replace(word, replacement))

আপনার উত্তরটি ইতিমধ্যে এই প্রশ্নটিতে উপস্থিত অন্যান্য উত্তরের উপরে উন্নত তা নিশ্চিত করুন।
হংসসি

এই ফাইলটি শেষে প্রতিস্থাপন পাঠ্য যোগ হবে, আমার মতে @Jack Aidley aswer ঠিক কি ওপি বোঝানো stackoverflow.com/a/17141572/6875391
কিরিল

-3
def findReplace(find, replace):

    import os 

    src = os.path.join(os.getcwd(), os.pardir) 

    for path, dirs, files in os.walk(os.path.abspath(src)):

        for name in files: 

            if name.endswith('.py'): 

                filepath = os.path.join(path, name)

                with open(filepath) as f: 

                    s = f.read()

                s = s.replace(find, replace) 

                with open(filepath, "w") as f:

                    f.write(s) 
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.