নির্দিষ্ট এক্সটেনশন সহ সমস্ত ফাইল সন্ধান এবং প্রতিস্থাপনের পাওয়ারশেল স্ক্রিপ্ট


123

উইন্ডোজ সার্ভার ২০০৮ এ আমার বেশ কয়েকটি কনফিগারেশন ফাইল রয়েছে যেমন নীস্টযুক্ত:

C:\Projects\Project_1\project1.config

C:\Projects\Project_2\project2.config

আমার কনফিগারেশনে আমার মতো স্ট্রিং প্রতিস্থাপন করা দরকার:

<add key="Environment" value="Dev"/>

হয়ে যাবে:

<add key="Environment" value="Demo"/>

আমি ব্যাচ স্ক্রিপ্টিং ব্যবহার সম্পর্কে ভেবেছিলাম, তবে এটি করার কোনও ভাল উপায় ছিল না এবং আমি শুনেছি যে পাওয়ারশেল স্ক্রিপ্টিং দিয়ে আপনি সহজেই এটি সম্পাদন করতে পারবেন can আমি সন্ধান / প্রতিস্থাপনের উদাহরণগুলি পেয়েছি, তবে আমি এমন একটি উপায়ের জন্য প্রত্যাশা করছিলাম যা আমার সি এর মধ্যে সমস্ত ফোল্ডারকে অতিক্রম করবে: directory প্রকল্পের ডিরেক্টরিতে এবং '.config' এক্সটেনশনের সাথে শেষ হওয়া কোনও ফাইল সন্ধান করবে। এটি যখন একটি সন্ধান করে, আমি এটি চাই আমার স্ট্রিংয়ের মানগুলি প্রতিস্থাপন করতে।

এটি কীভাবে করবেন বা কোনও পাওয়ারশেল গুরু যা কিছু অন্তর্দৃষ্টি দিতে পারে তা জানতে কোনও ভাল সংস্থান?


1
আপনি কীভাবে এসেছেন বা ফাইলগুলিতে কিছু অদ্ভুত বিন্যাসের সমস্যা রয়েছে যা মোকাবিলা করার দরকার রয়েছে তা আমাদের জানান। সমস্যাটির একটি ভাল বিষয় হ'ল এটি প্রোডাকশন
কোডকে

উত্তর:


178

এখানে আমার মাথার শীর্ষে প্রথম চেষ্টা।

$configFiles = Get-ChildItem . *.config -rec
foreach ($file in $configFiles)
{
    (Get-Content $file.PSPath) |
    Foreach-Object { $_ -replace "Dev", "Demo" } |
    Set-Content $file.PSPath
}

3
আমি যুক্ত করতে চাই যে সমস্ত কাজগুলি সরবরাহ করা সমাধানগুলি পরীক্ষা করে, তবে এটি পাঠযোগ্যতার পক্ষে সহজতম। আমি এটি কোনও সহকর্মীর হাতে দিতে সক্ষম হয়েছি এবং তিনি সহজেই বুঝতে পারছেন যে কী চলছে। সহায়তার জন্য ধন্যবাদ।
ব্র্যান্ডন

11
উপ-ডিরেক্টরিতে ফাইলগুলিতে কাজ করার জন্য আপনার ".PSPath" দরকার। মজার বিষয় হচ্ছে, আমি যখন এই কাজটি একটি () -র কাছাকাছি না করে তৈরি করার চেষ্টা করেছি তখন এটি লিখিত-সামগ্রীতে ব্যর্থ হয়েছিল কারণ ফাইলটি লক হয়ে গিয়েছিল।
ফ্রাঙ্ক শুইটারম্যান

25
সংক্ষিপ্ত সংস্করণ (সাধারণ নাম ব্যবহার করা হয়েছে):ls *.config -rec | %{ $f=$_; (gc $f.PSPath) | %{ $_ -replace "Dev", "Demo" } | sc $f.PSPath }
আরটিম

5
@Artyom ভুলবেন না .পরে ls। আমি নিজেই তা খেয়েছি।
পিওরফেরেট

5
আপনি যদি সমস্ত ফাইলগুলিতে চালানোর জন্য * .config মুছে ফেলেন তবে অননুমোদিতঅ্যাক্সেসএক্সসেপশন ফোল্ডারগুলির কারণেও হতে পারে। আপনি গেট-চাইল্ড আইটেমটিতে ফাইল ফিল্টার যুক্ত করতে পারেন ... এটি বের করতে কিছুক্ষণ সময় লাগল
আমির কাটজ

32

পাওয়ারশেল একটি ভাল পছন্দ;) প্রদত্ত ডিরেক্টরিতে ফাইলগুলি গণনা করা, সেগুলি পড়া এবং প্রক্রিয়া করা খুব সহজ।

স্ক্রিপ্টটি এর মতো দেখতে পারে:

Get-ChildItem C:\Projects *.config -recurse |
    Foreach-Object {
        $c = ($_ | Get-Content) 
        $c = $c -replace '<add key="Environment" value="Dev"/>','<add key="Environment" value="Demo"/>'
        [IO.File]::WriteAllText($_.FullName, ($c -join "`r`n"))
    }

আপনার জন্য পঠনযোগ্য হওয়ার জন্য আমি কোডটি আরও লাইনে বিভক্ত করেছি। মনে রাখবেন আপনি এর পরিবর্তে সেট-সামগ্রী ব্যবহার করতে পারেন [IO.File]::WriteAllTextতবে এটি শেষে নতুন লাইন যুক্ত করে। WriteAllTextআপনি এড়াতে পারেন সঙ্গে ।

তা না হলে কোডটির এই মত চেহারা পারে: $c | Set-Content $_.FullName


14

এই পদ্ধতির ভাল কাজ করে:

gci C:\Projects *.config -recurse | ForEach {
  (Get-Content $_ | ForEach {$_ -replace "old", "new"}) | Set-Content $_ 
}
  • "পুরানো" এবং "নতুন "টিকে তাদের সম্পর্কিত মানগুলিতে পরিবর্তন করুন (বা ভেরিয়েবল ব্যবহার করুন)।
  • প্রথম বন্ধনীটি ভুলে যাবেন না - এগুলি ছাড়া আপনি কোনও অ্যাক্সেস ত্রুটি পাবেন।

সুতরাং আমি সংক্ষিপ্ত অভিব্যক্তির জন্য এটির সাথে গিয়েছিলাম - তবে আমাকে এটির Get-Content $_সাথে প্রতিস্থাপন করতে হয়েছিল Get-Content $_.FullName, এবং Set-Contentএর মূল হিসাবে থাকা ফাইলগুলি হ্যান্ডেল করার জন্য এটির সমতুল্য ছিল।
ম্যাট হুইটফিল্ড

11

আমি এক্সএমএল এবং এক্সপথ সহ যাব:

dir C:\Projects\project_*\project*.config -recurse | foreach-object{  
   $wc = [xml](Get-Content $_.fullname)
   $wc.SelectNodes("//add[@key='Environment'][@value='Dev']") | Foreach-Object {$_.value = 'Demo'}  
   $wc.Save($_.fullname)  
}

11

এই পাওয়ারশেল উদাহরণটি কোনও ফোল্ডার এবং তার সাবফোল্ডারগুলির "\ foo \" স্ট্রিংয়ের সমস্ত উদাহরণ সন্ধান করে, "\ foo \" কে "\ বার \" দিয়ে প্রতিস্থাপন করে এবং "\ foo \" স্ট্রিং না থাকা ফাইলগুলিকে পুনরায় মূল্যায়ন করে না "এইভাবে আপনি ফাইলটি সর্বশেষ আপডেটের তারিখ-সময়ের স্ট্যাম্পগুলিকে ধ্বংস করবেন না যেখানে স্ট্রিংটি পাওয়া যায় নি:

Get-ChildItem  -Path C:\YOUR_ROOT_PATH\*.* -recurse 
 | ForEach {If (Get-Content $_.FullName | Select-String -Pattern '\\foo\\') 
           {(Get-Content $_ | ForEach {$_ -replace '\\foo\\', '\bar\'}) | Set-Content $_ }
           }

7

আমি @ আর্টিয়ামের মন্তব্যটি দরকারী বলে খুঁজে পেয়েছি তবে দুর্ভাগ্যক্রমে তিনি কোনও উত্তর পোস্ট করেননি।

এটি স্বীকৃত উত্তরের আমার মতে সেরা সংস্করণটি হ'ল সংক্ষিপ্ত সংস্করণ;

ls *.config -rec | %{$f=$_; (gc $f.PSPath) | %{$_ -replace "Dev", "Demo"} | sc $f.PSPath}

1
যদি অন্য কেউ এটিকে চালিয়ে যায়, যেমনটি আমি করেছিলাম - এটি সরাসরি কোনও ব্যাচের ফাইল থেকে চালানোর জন্য খুঁজছেন - এটি যেমন কোনও কমান্ড কার্যকর করার সময় এটির foreach-objectপরিবর্তে %উলামের পরিবর্তে ব্যবহার করতে সহায়তা করে । অন্যথায়, এটি ত্রুটির ফলস্বরূপ হতে পারে:Expressions are only allowed as the first element of a pipeline
ডাস্টিন হালসটেড

সংক্ষিপ্তটি সবসময় ভাল হয় না, এটি দীর্ঘ সংস্করণে কী ঘটছে তা আরও স্পষ্ট।
নিক এন।

@NickN। ঠিক আছে, ঠিক আছে। এটি আপনার উদ্দেশ্য কী তার উপর নির্ভর করে। আমি এটি পিওবি হিসাবে পতাকাঙ্কিত করব;)
এম-- 21'19

6

আমি কোনও ফাইলে পাঠ্য প্রতিস্থাপন করতে একটু সহায়ক ফাংশন লিখেছি:

function Replace-TextInFile
{
    Param(
        [string]$FilePath,
        [string]$Pattern,
        [string]$Replacement
    )

    [System.IO.File]::WriteAllText(
        $FilePath,
        ([System.IO.File]::ReadAllText($FilePath) -replace $Pattern, $Replacement)
    )
}

উদাহরণ:

Get-ChildItem . *.config -rec | ForEach-Object { 
    Replace-TextInFile -FilePath $_ -Pattern 'old' -Replacement 'new' 
}

4

পুনরাবৃত্ত প্রতিস্থাপন করার সময়, পথ এবং ফাইলের নাম অন্তর্ভুক্ত করা দরকার:

Get-ChildItem -Recurse | ForEach {  (Get-Content $_.PSPath | 
ForEach {$ -creplace "old", "new"}) | Set-Content $_.PSPath }

এটি আপনার বর্তমান ডিরেক্টরিতে আপনার ফোল্ডারের সমস্ত ফাইলে "পুরানো" কে "নতুন" কেস-সংবেদনশীল সহ প্রতিস্থাপন করবে।


আপনার উত্তরের ".পিএসপ্যাথ" অংশটি আমাকে সত্যই সহায়তা করেছিল। তবে আমাকে অভ্যন্তরীণ "$" "" "$ _" এ পরিবর্তন করতে হয়েছিল। আমি তোমার উত্তরের সম্পাদনা করতে হবে, কিন্তু আমি তোমার -creplace অংশ ব্যবহার করছি না - আমি ভালো .PSPath সঙ্গে গৃহীত উত্তর ব্যবহার
bbbb সেও কি মুসলিম ছিল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.