คุณจะค้นหาและแทนที่ข้อความในไฟล์โดยใช้สภาพแวดล้อมบรรทัดคำสั่งของ Windows ได้อย่างไร


492

ฉันกำลังเขียนสคริปต์ไฟล์แบตช์โดยใช้สภาพแวดล้อมบรรทัดคำสั่งของ Windows และต้องการเปลี่ยนข้อความที่เกิดขึ้นในแต่ละไฟล์ (เช่น "FOO") ด้วยอีกไฟล์หนึ่ง (เช่น "BAR") วิธีที่ง่ายที่สุดในการทำเช่นนั้นคืออะไร? ฟังก์ชั่นใด ๆ ในตัว?



ใช้นี้echo(%text:%search%=%replace%%)
scientist_7

คำตอบ:


308

คำตอบมากมายที่นี่ช่วยชี้ทางให้ฉันในทิศทางที่ถูกต้องอย่างไรก็ตามไม่มีคำตอบที่เหมาะสมสำหรับฉันดังนั้นฉันจึงโพสต์คำตอบของฉัน

ฉันมี Windows 7 ซึ่งมาพร้อมกับ PowerShell ในตัว นี่คือสคริปต์ที่ฉันใช้ในการค้นหา / แทนที่ข้อความทั้งหมดในไฟล์:

powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"

เพื่ออธิบาย:

  • powershell เริ่มต้น powershell.exe ซึ่งรวมอยู่ใน Windows 7
  • -Command "... " เป็นบรรทัดคำสั่งหาเรื่องสำหรับ powershell.exe ที่มีคำสั่งให้ทำงาน
  • (gc myFile.txt)อ่านเนื้อหาของmyFile.txt( gcสั้นสำหรับGet-Contentคำสั่ง)
  • -replace 'foo', 'bar'เพียงแค่รันคำสั่ง replace เพื่อแทนที่fooด้วยbar
  • | Out-File myFile.txt ไพพ์เอาต์พุตไปยังไฟล์ myFile.txt
  • -encoding ASCII ป้องกัน transcribing ไฟล์ที่ส่งออกไปยัง Unicode ตามความเห็นชี้ให้เห็น

Powershell.exe ควรเป็นส่วนหนึ่งของคำสั่ง PATH ของคุณอยู่แล้ว แต่ถ้าไม่คุณสามารถเพิ่มได้ ตำแหน่งของมันบนเครื่องของฉันคือC:\WINDOWS\system32\WindowsPowerShell\v1.0


71
ระวังคำสั่งนี้อาจแปลงไฟล์เป็นการเข้ารหัส Unicode คุณสามารถระบุการเข้ารหัสด้วยตนเองโดยการเพิ่ม-encoding ASCIIหรือUTF8หรืออะไรก็ตามที่จำเป็น นอกจากนี้ระวังถ้าคุณกำหนดเป้าหมายเป็น UTF8 มันอาจแนะนำ Byte Order Mark ที่จุดเริ่มต้นของไฟล์ที่ไม่ปรากฏในต้นฉบับ
Wyck

78
@Wyck -encoding ASCIIมันเอาฉันในขณะที่จะคิดออกว่าจะใส่ สำหรับทุกคนที่ต้องการมันในอนาคตมันจะเป็นOut-File -encoding ASCII myFile.txt
rwilson04

15
สิ่งเดียวที่ฉันมีการเปลี่ยนแปลงคือการใช้แทนSet-Content Out-File
kurtzmarc

6
วิธีนี้ใช้งานได้ แต่ประสิทธิภาพนั้นแย่มากแม้กระทั่งรายชื่อไฟล์ที่สั้น
jsuddsjr

23
ระวังว่าโทเค็นการแทนที่ ('foo' ในกรณีนี้) ถือว่าเป็นนิพจน์ทั่วไป หากคุณมีตัวละครพิเศษใด ๆ (ฉันมี []) คุณจะต้องเพิ่มพวกเขาด้วย \ (แบ็กสแลช)
JW

183

หากคุณใช้ Windows เวอร์ชั่นที่รองรับ. Net 2.0 ฉันจะแทนที่เชลล์ของคุณ PowerShellให้อำนาจเต็มของ. Net จากบรรทัดคำสั่ง มี commandlets มากมายในตัวเช่นกัน ตัวอย่างด้านล่างจะแก้ปัญหาของคุณ ฉันใช้ชื่อเต็มของคำสั่งมีนามแฝงที่สั้นกว่า แต่สิ่งนี้ให้สิ่งแก่คุณใน Google

(Get-Content test.txt) | ForEach-Object { $_ -replace "foo", "bar" } | Set-Content test2.txt

10
ฉันเห็นว่า PowerShell สามารถเก็บเรื่องนี้ไว้ได้ แต่ฉันจะทำการรันจากไฟล์แบตช์ได้อย่างไร (ตัวอย่าง: myProc.bat)
Pablo Venturino

3
@Pablo ใช้ powershell.exe และคำสั่งห่อ PS เข้าไปในพารามิเตอร์เดียว
Lubos hasko

56
-1 .. แน่ใจว่าได้รับคำตอบแล้ว แต่ไม่ใช่คำตอบสำหรับคำถามที่ระบุ
baash05

28
สิ่งนี้จะล้มเหลวด้วยไฟล์ที่ใช้งานผิดพลาดหากคุณบันทึกเป็นไฟล์เดียวกัน คุณต้องเปลี่ยนคำสั่ง powershell เป็น: (Get-Content test.txt) | ForEach-Object {$ _ -replace "foo", "bar"} | Set-Content test.txt
BigMomma

6
ดูคำตอบจาก @Rachel:powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | sc myFile.txt"
Nigel Touch

161

เพิ่งใช้FART (" F ind A nd Rยูทิลิตี้บรรทัดคำสั่ง eplace T ext"):
ฟรีแวร์ที่ยอดเยี่ยมเล็กน้อยสำหรับการเปลี่ยนข้อความภายในชุดไฟล์ขนาดใหญ่

ไฟล์ติดตั้งอยู่บน SourceForgeSourceForge

ตัวอย่างการใช้งาน:

fart.exe -p -r -c -- C:\tools\perl-5.8.9\* @@APP_DIR@@ C:\tools

จะแสดงตัวอย่างการแทนที่เพื่อทำซ้ำในไฟล์ของการกระจาย Perl นี้

ปัญหาเท่านั้น: ไอคอนเว็บไซต์ FART ไม่ได้มีรสนิยมดีเลิศหรือหรูหรา;)


อัปเดต 2017 (7 ปีต่อมา) jagbชี้ให้เห็นในความคิดเห็นของบทความ 2011 " FARTing the Easy Way - ค้นหาและแทนที่ข้อความ " จากMikail Tunç


19
สิ่งที่ยอดเยี่ยมคือมันเป็น exe ตัวเดียว ไม่มีการพึ่งพา ไม่มีงานพิมพ์ขนาดเล็ก ง่ายต่อการปรับใช้
Serge Wautier

2
น้ำหนักเบามากและใช้งานง่าย แต่ฉันหวังว่ามันจะพิมพ์สถานที่ที่แน่นอนที่เกิดขึ้นแทน การไม่สามารถมองเห็นสิ่งนั้นทำให้ฉันรู้สึกไม่มั่นคง
William Niu

4
ขอบคุณมันสมบูรณ์แบบควรเป็นส่วนหนึ่งของเครื่องมือดอสมาตรฐานและสร้างเสน่ห์ ตัวเลือก -p ไม่ได้แสดงให้คุณเห็นว่าจะมีการเปลี่ยนแปลงกี่ครั้งและรายงาน 0 ซึ่งทำให้ฉันไม่กี่นาที
เสมอ

3
ฉันเข้าใจว่านี่เป็นคำถามที่เก่ามาก แต่ฉันพบข้อมูลเพิ่มเติมและหวังว่ามันจะมีประโยชน์สำหรับผู้ใช้ Stack Overflow ลิงค์อื่นสำหรับ FART ที่อธิบายผลิตภัณฑ์ได้ดี: FART explaned @ emtunc.orgและอีกหน้าสามารถพบได้ที่นี่: FART โปรดใช้ความระมัดระวังในการเปลี่ยน/และ'เนื่องจากนี่ไม่ได้ผลสำหรับเราทุกคนสำหรับฉันมันทำงานในบางส่วน เคส แต่มันใช้ไม่ได้กับไฟล์บางไฟล์และฉันไม่รู้ว่าทำไม .. ฉันใช้สิ่งนี้เพื่อแทนที่ข้อความด้วยข้อความอื่นและ a/
jagb

4
@jagb ขอบคุณ ฉันได้รวมลิงค์ของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น
VonC

128

แทนที่ - แทนที่สตริงย่อยโดยใช้การแทนที่สตริงคำอธิบาย: ในการแทนที่สตริงย่อยด้วยสตริงอื่นให้ใช้คุณสมบัติการแทนที่สตริง ตัวอย่างที่แสดงที่นี่แทนที่การสะกดคำผิด "teh" ทั้งหมดด้วย "the" ในตัวแปรสตริง str

set str=teh cat in teh hat
echo.%str%
set str=%str:teh=the%
echo.%str%

เอาต์พุตสคริปต์:

teh cat in teh hat
the cat in the hat

อ้างอิง: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.Replace


30
การแนะนำที่ดีกว่านี้เป็นอย่างไร? นี่ดูเหมือนจะเป็นคำตอบที่ง่ายที่สุดของพวกเขาทั้งหมดและไม่ต้องติดตั้งอะไรเลย
DonBecker

5
การจับคู่รูปแบบใด ๆ สามารถทำได้ที่นี่หรือไม่ Wildcards, Regex และอื่น ๆ ?
Keyo

27
"การแนะนำที่ดีกว่านี้เป็นอย่างไร" - sed และยูทิลิตี้ที่คล้ายกันทำงานกับไฟล์ ตัวอย่างนี้ละเว้นขั้นตอนสำคัญของการอ่านบรรทัดจากไฟล์อินพุตและเขียนไปยังไฟล์เอาต์พุตในขณะที่ตรวจสอบให้แน่ใจว่าอักขระพิเศษใด ๆ ในไฟล์ถูกจัดการอย่างถูกต้อง
Joe

7
@ Asad ใช่ว่าจริง OP ได้ถามเกี่ยวกับไฟล์ แต่ในความเป็นจริงมันทำงานร่วมกับกระแสซึ่งไม่จำเป็นต้องเป็นไฟล์ แต่ประเด็นของฉันตรงนี้ก็คือคำตอบนี้มีข้อบกพร่องเพราะมันไม่ได้อ่าน / เขียนจากสตรีมและจัดการอักขระพิเศษใด ๆ
โจ

4
@Bill วิธีการใช้ตัวแปรเป็นข้อความแทนที่? กล่าวคือ ฉันมีค่าในตัวแปรและสตริงที่มีตัวคั่นบางอย่าง set str =% str: "##" =% varValue %% ไม่ทำงาน วิธีแก้ปัญหาใด ๆ
MalTec

55

สร้างไฟล์ replace.vbs:

Const ForReading = 1    
Const ForWriting = 2

strFileName = Wscript.Arguments(0)
strOldText = Wscript.Arguments(1)
strNewText = Wscript.Arguments(2)

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(strFileName, ForReading)
strText = objFile.ReadAll
objFile.Close

strNewText = Replace(strText, strOldText, strNewText)
Set objFile = objFSO.OpenTextFile(strFileName, ForWriting)
objFile.Write strNewText  'WriteLine adds extra CR/LF
objFile.Close

ในการใช้สคริปต์ที่แก้ไขนี้ (ซึ่งเราจะเรียกใช้งาน replace.vbs) เพียงพิมพ์คำสั่งที่คล้ายกับสิ่งนี้จากพรอมต์คำสั่ง:

cscript replace.vbs "C:\Scripts\Text.txt" "Jim " "James "


นี่เป็นระเบียบมันอนุญาตให้ใช้ RegEx หรือไม่
user280109

3
@ user280109 ใช่ VBScript RegExpสนับสนุน With (New RegExp): strNewText = .Replace(strText, strOldText, strNewText): End Withคุณสามารถใช้นี้เพื่อแทนที่การใช้นิพจน์ปกติ: คุณจะได้รับข้อความแรก 9 กลุ่มจับใช้$1,$2$9 ...
แปรงสีฟัน

2
VBScript มักถูกมองข้าม (และเกลียดชัง) แต่สามารถใช้งานได้บนแพลตฟอร์ม Windows ทั้งหมดสามารถอ่านได้และมีความสามารถที่ทรงพลังมากจริง ๆ +1
zelanix

1
@ user280109 คุณเพิ่งได้รับคำสั่งสิ่งที่ฉันต้องการ แต่ฉันต้องการแทนที่ (ตัวพิมพ์เล็กและตัวพิมพ์ใหญ่) คุณสามารถให้คำสั่งสำหรับสิ่งนั้นได้หรือไม่?
Ajmal Praveen

49

BatchSubstitute.batบน dostips.comเป็นตัวอย่างของการค้นหาและแทนที่โดยใช้ไฟล์แบตช์บริสุทธิ์

โดยจะใช้การรวมกันของFOR, และFINDCALL SET

บรรทัดที่มีอักขระที่อยู่ในกลุ่ม"&<>]|^อาจถือว่าไม่ถูกต้อง



8
ฉันต้องถามถึงประโยชน์ของไซต์โค้ดขนาดเล็กที่มีข้อกำหนดการใช้งานห้ามคัดลอกโค้ดใด ๆ (“ คุณไม่สามารถเผยแพร่ข้อมูลใด ๆ ที่ให้ไว้ภายใต้โดเมน dostips.com ในรูปแบบใด ๆ โดยไม่ได้รับอนุญาตเป็นลายลักษณ์อักษรจากเจ้าของโดเมน”) .
Gilles 'หยุดความชั่วร้าย'

1
ฉันเห็นด้วยกับข้อตกลงของพวกเขาสับสนพวกเขายังพูดว่า "ข้อมูลที่ให้ไว้ภายใต้โดเมน dostips.com นั้นมีประโยชน์อย่างหวังว่า" ดังนั้นข้อสันนิษฐานของฉันคือพวกเขายินดีให้ผู้คนคัดลอกรหัสเพื่อแก้ไขปัญหา ฉันไม่แน่ใจว่าฉันได้อ่านข้อกำหนดและเงื่อนไขใด ๆ แล้วและมีความสุข ...
morechilli

5
มันเยี่ยมมาก ฉันชอบคำตอบที่ไม่เกี่ยวข้องกับการดาวน์โหลดอย่างอื่น
Ruairi O'Brien

ฉันชอบโซลูชันที่ไม่เกี่ยวข้องกับยูทิลิตี้ภายนอกขออภัยฉันได้รับ "ค้นหา: เพรดิเคตที่ไม่ถูกต้อง` `" เมื่อฉันพยายามเรียกใช้ชุดข้อมูลนี้ ยังไม่มีเวลาแก้ไขข้อบกพร่องจริงๆในขณะนี้
Jahmic

2
ข้อผิดพลาด "ค้นหา: เพรดิเคต` `` ที่ไม่ถูกต้องเกิดจากยูทิลิตี้ 'ค้นหา' ภายนอกในระบบของฉัน เมื่อลบออกแล้วก็ใช้งานได้ดี
Jahmic

47

หมายเหตุ - ให้แน่ใจว่าได้เห็นการปรับปรุงในตอนท้ายของคำตอบนี้สำหรับการเชื่อมโยงไปยัง JREPL.BAT ที่เหนือกว่าซึ่งแทนที่ REPL.BAT
JATPL.BAT BAT 7.0 และสูงกว่าสนับสนุน Unicode (UTF-16LE) ผ่านทาง/UTFตัวเลือกเช่นเดียวกัน ชุดอักขระอื่นรวมถึง UTF-8 ผ่าน ADO !!!!


ฉันได้เขียนยูทิลิตี้ JScript / batch ขนาดเล็กซึ่งเรียกว่า REPL.BATซึ่งสะดวกมากสำหรับการแก้ไขไฟล์ ASCII (หรือ ASCII แบบขยาย) ผ่านทางบรรทัดคำสั่งหรือแบตช์ไฟล์ สคริปต์เนทีฟอย่างแท้จริงไม่ต้องการการติดตั้งโปรแกรมที่ดำเนินการโดยบุคคลที่สามใด ๆ และทำงานได้กับ Windows ทุกรุ่นตั้งแต่ XP เป็นต้นไป นอกจากนี้ยังรวดเร็วมากโดยเฉพาะเมื่อเปรียบเทียบกับโซลูชันแบตช์บริสุทธิ์

REPL.BAT เพียงแค่อ่าน stdin ทำการค้นหาและแทนที่ JScript regex และเขียนผลลัพธ์ไปยัง stdout

นี่คือตัวอย่างเล็กน้อยของวิธีการแทนที่ foo ด้วยแถบใน test.txt โดยสมมติว่า REPL.BAT อยู่ในโฟลเดอร์ปัจจุบันของคุณหรือดีกว่ายังที่ใดที่หนึ่งภายใน PATH ของคุณ:

type test.txt|repl "foo" "bar" >test.txt.new
move /y test.txt.new test.txt

ความสามารถในการ regex JScript ทำให้มันมีประสิทธิภาพมากโดยเฉพาะอย่างยิ่งความสามารถของข้อความทดแทนเพื่ออ้างอิง substrings จับจากข้อความค้นหา

ฉันได้รวมตัวเลือกมากมายในยูทิลิตี้ที่ทำให้มันมีประสิทธิภาพมาก ตัวอย่างเช่นการรวมMและXตัวเลือกช่วยให้สามารถปรับเปลี่ยนไฟล์ไบนารี! Mตัวเลือกหลายสายช่วยให้การค้นหาในหลายสาย Xตัวเลือกรูปแบบการแทนให้ขยายลำดับหนีที่ช่วยให้การรวมของค่าไบนารีใด ๆ ในข้อความทดแทน

ยูทิลิตีทั้งหมดอาจเขียนเป็น JScript แท้ แต่ชุดไฟล์ไฮบริดไม่จำเป็นต้องระบุ CSCRIPT ทุกครั้งที่คุณต้องการใช้ยูทิลิตี้

นี่คือสคริปต์ REPL.BAT เอกสารแบบเต็มจะถูกฝังอยู่ภายในสคริปต์

@if (@X)==(@Y) @end /* Harmless hybrid line that begins a JScript comment

::************ Documentation ***********
::REPL.BAT version 6.2
:::
:::REPL  Search  Replace  [Options  [SourceVar]]
:::REPL  /?[REGEX|REPLACE]
:::REPL  /V
:::
:::  Performs a global regular expression search and replace operation on
:::  each line of input from stdin and prints the result to stdout.
:::
:::  Each parameter may be optionally enclosed by double quotes. The double
:::  quotes are not considered part of the argument. The quotes are required
:::  if the parameter contains a batch token delimiter like space, tab, comma,
:::  semicolon. The quotes should also be used if the argument contains a
:::  batch special character like &, |, etc. so that the special character
:::  does not need to be escaped with ^.
:::
:::  If called with a single argument of /?, then prints help documentation
:::  to stdout. If a single argument of /?REGEX, then opens up Microsoft's
:::  JScript regular expression documentation within your browser. If a single
:::  argument of /?REPLACE, then opens up Microsoft's JScript REPLACE
:::  documentation within your browser.
:::
:::  If called with a single argument of /V, case insensitive, then prints
:::  the version of REPL.BAT.
:::
:::  Search  - By default, this is a case sensitive JScript (ECMA) regular
:::            expression expressed as a string.
:::
:::            JScript regex syntax documentation is available at
:::            http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx
:::
:::  Replace - By default, this is the string to be used as a replacement for
:::            each found search expression. Full support is provided for
:::            substituion patterns available to the JScript replace method.
:::
:::            For example, $& represents the portion of the source that matched
:::            the entire search pattern, $1 represents the first captured
:::            submatch, $2 the second captured submatch, etc. A $ literal
:::            can be escaped as $$.
:::
:::            An empty replacement string must be represented as "".
:::
:::            Replace substitution pattern syntax is fully documented at
:::            http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx
:::
:::  Options - An optional string of characters used to alter the behavior
:::            of REPL. The option characters are case insensitive, and may
:::            appear in any order.
:::
:::            A - Only print altered lines. Unaltered lines are discarded.
:::                If the S options is present, then prints the result only if
:::                there was a change anywhere in the string. The A option is
:::                incompatible with the M option unless the S option is present.
:::
:::            B - The Search must match the beginning of a line.
:::                Mostly used with literal searches.
:::
:::            E - The Search must match the end of a line.
:::                Mostly used with literal searches.
:::
:::            I - Makes the search case-insensitive.
:::
:::            J - The Replace argument represents a JScript expression.
:::                The expression may access an array like arguments object
:::                named $. However, $ is not a true array object.
:::
:::                The $.length property contains the total number of arguments
:::                available. The $.length value is equal to n+3, where n is the
:::                number of capturing left parentheses within the Search string.
:::
:::                $[0] is the substring that matched the Search,
:::                $[1] through $[n] are the captured submatch strings,
:::                $[n+1] is the offset where the match occurred, and
:::                $[n+2] is the original source string.
:::
:::                Arguments $[0] through $[10] may be abbreviated as
:::                $1 through $10. Argument $[11] and above must use the square
:::                bracket notation.
:::
:::            L - The Search is treated as a string literal instead of a
:::                regular expression. Also, all $ found in the Replace string
:::                are treated as $ literals.
:::
:::            M - Multi-line mode. The entire contents of stdin is read and
:::                processed in one pass instead of line by line, thus enabling
:::                search for \n. This also enables preservation of the original
:::                line terminators. If the M option is not present, then every
:::                printed line is terminated with carriage return and line feed.
:::                The M option is incompatible with the A option unless the S
:::                option is also present.
:::
:::                Note: If working with binary data containing NULL bytes,
:::                      then the M option must be used.
:::
:::            S - The source is read from an environment variable instead of
:::                from stdin. The name of the source environment variable is
:::                specified in the next argument after the option string. Without
:::                the M option, ^ anchors the beginning of the string, and $ the
:::                end of the string. With the M option, ^ anchors the beginning
:::                of a line, and $ the end of a line.
:::
:::            V - Search and Replace represent the name of environment
:::                variables that contain the respective values. An undefined
:::                variable is treated as an empty string.
:::
:::            X - Enables extended substitution pattern syntax with support
:::                for the following escape sequences within the Replace string:
:::
:::                \\     -  Backslash
:::                \b     -  Backspace
:::                \f     -  Formfeed
:::                \n     -  Newline
:::                \q     -  Quote
:::                \r     -  Carriage Return
:::                \t     -  Horizontal Tab
:::                \v     -  Vertical Tab
:::                \xnn   -  Extended ASCII byte code expressed as 2 hex digits
:::                \unnnn -  Unicode character expressed as 4 hex digits
:::
:::                Also enables the \q escape sequence for the Search string.
:::                The other escape sequences are already standard for a regular
:::                expression Search string.
:::
:::                Also modifies the behavior of \xnn in the Search string to work
:::                properly with extended ASCII byte codes.
:::
:::                Extended escape sequences are supported even when the L option
:::                is used. Both Search and Replace support all of the extended
:::                escape sequences if both the X and L opions are combined.
:::
:::  Return Codes:  0 = At least one change was made
:::                     or the /? or /V option was used
:::
:::                 1 = No change was made
:::
:::                 2 = Invalid call syntax or incompatible options
:::
:::                 3 = JScript runtime error, typically due to invalid regex
:::
::: REPL.BAT was written by Dave Benham, with assistance from DosTips user Aacini
::: to get \xnn to work properly with extended ASCII byte codes. Also assistance
::: from DosTips user penpen diagnosing issues reading NULL bytes, along with a
::: workaround. REPL.BAT was originally posted at:
::: http://www.dostips.com/forum/viewtopic.php?f=3&t=3855
:::

::************ Batch portion ***********
@echo off
if .%2 equ . (
  if "%~1" equ "/?" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^:::" "" a
    exit /b 0
  ) else if /i "%~1" equ "/?regex" (
    explorer "http://msdn.microsoft.com/en-us/library/ae5bf541(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/?replace" (
    explorer "http://msdn.microsoft.com/en-US/library/efy6s3e6(v=vs.80).aspx"
    exit /b 0
  ) else if /i "%~1" equ "/V" (
    <"%~f0" cscript //E:JScript //nologo "%~f0" "^::(REPL\.BAT version)" "$1" a
    exit /b 0
  ) else (
    call :err "Insufficient arguments"
    exit /b 2
  )
)
echo(%~3|findstr /i "[^SMILEBVXAJ]" >nul && (
  call :err "Invalid option(s)"
  exit /b 2
)
echo(%~3|findstr /i "M"|findstr /i "A"|findstr /vi "S" >nul && (
  call :err "Incompatible options"
  exit /b 2
)
cscript //E:JScript //nologo "%~f0" %*
exit /b %errorlevel%

:err
>&2 echo ERROR: %~1. Use REPL /? to get help.
exit /b

************* JScript portion **********/
var rtn=1;
try {
  var env=WScript.CreateObject("WScript.Shell").Environment("Process");
  var args=WScript.Arguments;
  var search=args.Item(0);
  var replace=args.Item(1);
  var options="g";
  if (args.length>2) options+=args.Item(2).toLowerCase();
  var multi=(options.indexOf("m")>=0);
  var alterations=(options.indexOf("a")>=0);
  if (alterations) options=options.replace(/a/g,"");
  var srcVar=(options.indexOf("s")>=0);
  if (srcVar) options=options.replace(/s/g,"");
  var jexpr=(options.indexOf("j")>=0);
  if (jexpr) options=options.replace(/j/g,"");
  if (options.indexOf("v")>=0) {
    options=options.replace(/v/g,"");
    search=env(search);
    replace=env(replace);
  }
  if (options.indexOf("x")>=0) {
    options=options.replace(/x/g,"");
    if (!jexpr) {
      replace=replace.replace(/\\\\/g,"\\B");
      replace=replace.replace(/\\q/g,"\"");
      replace=replace.replace(/\\x80/g,"\\u20AC");
      replace=replace.replace(/\\x82/g,"\\u201A");
      replace=replace.replace(/\\x83/g,"\\u0192");
      replace=replace.replace(/\\x84/g,"\\u201E");
      replace=replace.replace(/\\x85/g,"\\u2026");
      replace=replace.replace(/\\x86/g,"\\u2020");
      replace=replace.replace(/\\x87/g,"\\u2021");
      replace=replace.replace(/\\x88/g,"\\u02C6");
      replace=replace.replace(/\\x89/g,"\\u2030");
      replace=replace.replace(/\\x8[aA]/g,"\\u0160");
      replace=replace.replace(/\\x8[bB]/g,"\\u2039");
      replace=replace.replace(/\\x8[cC]/g,"\\u0152");
      replace=replace.replace(/\\x8[eE]/g,"\\u017D");
      replace=replace.replace(/\\x91/g,"\\u2018");
      replace=replace.replace(/\\x92/g,"\\u2019");
      replace=replace.replace(/\\x93/g,"\\u201C");
      replace=replace.replace(/\\x94/g,"\\u201D");
      replace=replace.replace(/\\x95/g,"\\u2022");
      replace=replace.replace(/\\x96/g,"\\u2013");
      replace=replace.replace(/\\x97/g,"\\u2014");
      replace=replace.replace(/\\x98/g,"\\u02DC");
      replace=replace.replace(/\\x99/g,"\\u2122");
      replace=replace.replace(/\\x9[aA]/g,"\\u0161");
      replace=replace.replace(/\\x9[bB]/g,"\\u203A");
      replace=replace.replace(/\\x9[cC]/g,"\\u0153");
      replace=replace.replace(/\\x9[dD]/g,"\\u009D");
      replace=replace.replace(/\\x9[eE]/g,"\\u017E");
      replace=replace.replace(/\\x9[fF]/g,"\\u0178");
      replace=replace.replace(/\\b/g,"\b");
      replace=replace.replace(/\\f/g,"\f");
      replace=replace.replace(/\\n/g,"\n");
      replace=replace.replace(/\\r/g,"\r");
      replace=replace.replace(/\\t/g,"\t");
      replace=replace.replace(/\\v/g,"\v");
      replace=replace.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      replace=replace.replace(/\\B/g,"\\");
    }
    search=search.replace(/\\\\/g,"\\B");
    search=search.replace(/\\q/g,"\"");
    search=search.replace(/\\x80/g,"\\u20AC");
    search=search.replace(/\\x82/g,"\\u201A");
    search=search.replace(/\\x83/g,"\\u0192");
    search=search.replace(/\\x84/g,"\\u201E");
    search=search.replace(/\\x85/g,"\\u2026");
    search=search.replace(/\\x86/g,"\\u2020");
    search=search.replace(/\\x87/g,"\\u2021");
    search=search.replace(/\\x88/g,"\\u02C6");
    search=search.replace(/\\x89/g,"\\u2030");
    search=search.replace(/\\x8[aA]/g,"\\u0160");
    search=search.replace(/\\x8[bB]/g,"\\u2039");
    search=search.replace(/\\x8[cC]/g,"\\u0152");
    search=search.replace(/\\x8[eE]/g,"\\u017D");
    search=search.replace(/\\x91/g,"\\u2018");
    search=search.replace(/\\x92/g,"\\u2019");
    search=search.replace(/\\x93/g,"\\u201C");
    search=search.replace(/\\x94/g,"\\u201D");
    search=search.replace(/\\x95/g,"\\u2022");
    search=search.replace(/\\x96/g,"\\u2013");
    search=search.replace(/\\x97/g,"\\u2014");
    search=search.replace(/\\x98/g,"\\u02DC");
    search=search.replace(/\\x99/g,"\\u2122");
    search=search.replace(/\\x9[aA]/g,"\\u0161");
    search=search.replace(/\\x9[bB]/g,"\\u203A");
    search=search.replace(/\\x9[cC]/g,"\\u0153");
    search=search.replace(/\\x9[dD]/g,"\\u009D");
    search=search.replace(/\\x9[eE]/g,"\\u017E");
    search=search.replace(/\\x9[fF]/g,"\\u0178");
    if (options.indexOf("l")>=0) {
      search=search.replace(/\\b/g,"\b");
      search=search.replace(/\\f/g,"\f");
      search=search.replace(/\\n/g,"\n");
      search=search.replace(/\\r/g,"\r");
      search=search.replace(/\\t/g,"\t");
      search=search.replace(/\\v/g,"\v");
      search=search.replace(/\\x[0-9a-fA-F]{2}|\\u[0-9a-fA-F]{4}/g,
        function($0,$1,$2){
          return String.fromCharCode(parseInt("0x"+$0.substring(2)));
        }
      );
      search=search.replace(/\\B/g,"\\");
    } else search=search.replace(/\\B/g,"\\\\");
  }
  if (options.indexOf("l")>=0) {
    options=options.replace(/l/g,"");
    search=search.replace(/([.^$*+?()[{\\|])/g,"\\$1");
    if (!jexpr) replace=replace.replace(/\$/g,"$$$$");
  }
  if (options.indexOf("b")>=0) {
    options=options.replace(/b/g,"");
    search="^"+search
  }
  if (options.indexOf("e")>=0) {
    options=options.replace(/e/g,"");
    search=search+"$"
  }
  var search=new RegExp(search,options);
  var str1, str2;

  if (srcVar) {
    str1=env(args.Item(3));
    str2=str1.replace(search,jexpr?replFunc:replace);
    if (!alterations || str1!=str2) if (multi) {
      WScript.Stdout.Write(str2);
    } else {
      WScript.Stdout.WriteLine(str2);
    }
    if (str1!=str2) rtn=0;
  } else if (multi){
    var buf=1024;
    str1="";
    while (!WScript.StdIn.AtEndOfStream) {
      str1+=WScript.StdIn.Read(buf);
      buf*=2
    }
    str2=str1.replace(search,jexpr?replFunc:replace);
    WScript.Stdout.Write(str2);
    if (str1!=str2) rtn=0;
  } else {
    while (!WScript.StdIn.AtEndOfStream) {
      str1=WScript.StdIn.ReadLine();
      str2=str1.replace(search,jexpr?replFunc:replace);
      if (!alterations || str1!=str2) WScript.Stdout.WriteLine(str2);
      if (str1!=str2) rtn=0;
    }
  }
} catch(e) {
  WScript.Stderr.WriteLine("JScript runtime error: "+e.message);
  rtn=3;
}
WScript.Quit(rtn);

function replFunc($0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10) {
  var $=arguments;
  return(eval(replace));
}


การอัปเดตที่สำคัญ

ฉันหยุดการพัฒนา REPL.BAT และแทนที่ด้วย JREPL.BAT ยูทิลิตี้ที่ใหม่กว่านี้มีฟังก์ชั่นการทำงานเหมือนกันทั้งหมดของ REPL.BAT รวมทั้งอื่น ๆ อีกมากมาย:

  • รองรับ Unicode UTF-16LE ผ่านความสามารถ unicode CSCRIPT และชุดอักขระอื่น ๆ (รวมถึง UTF-8) ผ่าน ADO
  • อ่านโดยตรงจาก / เขียนโดยตรงไปยังไฟล์: ไม่จำเป็นสำหรับไพพ์, การเปลี่ยนทิศทางหรือคำสั่งย้าย
  • รวม JScript ที่ผู้ใช้จัดหา
  • สิ่งอำนวยความสะดวกการแปลคล้ายกับ unix tr เพียง แต่รองรับการค้นหา regex และการแทนที่ JScript
  • ยกเลิกข้อความที่ไม่ตรงกัน
  • คำนำหน้าบรรทัดเอาต์พุตที่มีหมายเลขบรรทัด
  • และอื่น ๆ...

เช่นเคยเอกสารทั้งหมดจะถูกฝังอยู่ภายในสคริปต์

วิธีแก้ปัญหาแบบดั้งเดิมนั้นง่ายกว่าเดิม:

jrepl "foo" "bar" /f test.txt /o -

รุ่นปัจจุบันของ JREPL.BAT สามารถใช้ได้ที่ DosTips อ่านโพสต์ที่ตามมาทั้งหมดในเธรดเพื่อดูตัวอย่างการใช้งานและประวัติของการพัฒนา


สิ่งที่ยอดเยี่ยม! ฉันรักความเรียบง่ายของ b / c นี้และวิธีที่คุณสามารถปรับให้เข้ากับสคริปต์ใด ๆ ดังนั้นจึงเขียนโค้ด JS ได้มากกว่าชุดเส็งเคร็ง
Adaptabi

แก้ไข - เพิ่มตัวเลือก A เพื่อพิมพ์บรรทัดที่แก้ไขแล้วเท่านั้น ปรับปรุงตัวเลือก X เพื่อรองรับ\qการนำเสนอ"และตอนนี้ตัวอักษรการค้นหาสนับสนุนลำดับการยกเว้นทั้งหมดเมื่อรวมตัวเลือก L และ X
dbenham

@dbenham - +1 นี่เป็นวิธีที่ลื่นไหลมันจะมีประโยชน์สำหรับงานอื่น ๆ เช่นกัน ขอบคุณสำหรับการโพสต์
bw

แก้ไข - ฉันแก้ไขพฤติกรรมของ \ xnn เมื่อใช้ตัวเลือก X เพื่อให้รหัสแสดงรหัส ASCII แบบขยาย นอกจากนี้ยังเพิ่มตัวเลือกรุ่น / V
dbenham

9
@dbenham นี่คืออัญมณี ทำไมคุณไม่ใส่ GitHub หรือเป็น Gist? จะทำให้การกำหนดเวอร์ชันการติดตามการเผยแพร่ / การแจกจ่ายการแก้ไขและอื่น ๆ ง่ายขึ้น หากคุณต้องการความช่วยเหลือโปรดแจ้งให้เราทราบ
Atif Aziz

36

ใช้ FNR

ใช้fnrยูทิลิตี้ มันมีข้อดีมากกว่าfart:

  • นิพจน์ทั่วไป
  • GUI ตัวเลือก มี "สร้างปุ่มบรรทัดคำสั่ง" เพื่อสร้างข้อความบรรทัดคำสั่งเพื่อใส่ในไฟล์แบทช์
  • รูปแบบหลายบรรทัด: GUI ช่วยให้คุณทำงานกับรูปแบบหลายบรรทัดได้อย่างง่ายดาย ใน FART คุณต้องหลีกเลี่ยงการขึ้นบรรทัดใหม่ด้วยตนเอง
  • ช่วยให้คุณเลือกการเข้ารหัสไฟล์ข้อความ นอกจากนี้ยังมีตัวเลือกตรวจจับอัตโนมัติ

ดาวน์โหลด FNR ที่นี่: http://findandreplace.io/?z=codeplex

ตัวอย่างการใช้งาน: fnr --cl --dir "<Directory Path>" --fileMask "hibernate.*" --useRegEx --find "find_str_expression" --replace "replace_string"


1
นี่เป็นสิ่งที่ดี ความสามารถในการสร้างบรรทัดคำสั่งจากกุยนั้นเป็นคุณสมบัติที่ดีที่ทำให้ฉันไปได้อย่างรวดเร็ว
David Hammond

เครื่องมือที่มีประโยชน์มาก พยายามผายลมมาก่อน แต่เอกสารนั้นล้าสมัย
Artur Kędzior

เครื่องมือเจ๋ง ๆ มันยังรองรับการแสดงออกปกติ นี่คือสิ่งที่ผายลมหายไป
Dio Phung

1
ขอขอบคุณที่ระบุเครื่องมือนี้ Single exe การแทนที่ที่ยอดเยี่ยมสำหรับ FART ซึ่งไม่ได้รับการพัฒนาอีกต่อไป (และพลาด regex) และไวยากรณ์ PowerShell นั้นทนไม่ได้
Gras Double

สิ่งนี้มีประโยชน์มากที่สุด กำลังมองหาการแทนที่ grep + sed ใน windows มันใช้งานได้ดีมาก!
Serban Tanasa

25

ฉันไม่คิดว่าจะมีวิธีทำกับคำสั่งในตัว ฉันขอแนะนำให้คุณดาวน์โหลดบางสิ่งเช่นGnuwin32หรือUnxUtilsและใช้sedคำสั่ง (หรือดาวน์โหลดเท่านั้นsed):

sed -c s/FOO/BAR/g filename

2
ใช้ cygwin ( cygwin.com ) มันเป็นสิ่งที่ดีที่สุดถัดไปในการติดตั้ง linux
Andrew Johnson

มันจะดีกว่าถ้ามีวิธีแก้ปัญหาที่ไม่ต้องพึ่งพาการติดตั้ง cygwin การจัดการสตริง POSIX นั้นไม่ใช่เรื่องง่าย - การทำสิ่งนี้บน Windows เป็นสิ่งที่คลุมเครือกว่าเล็กน้อย
เร็กซ์

4
Gnuwin32 และ UnxUtils เป็นไบนารีแบบสแตนด์อโลนที่สร้างขึ้นสำหรับ Windows พวกเขาไม่ได้ขึ้นอยู่กับ cygwin
Ferruccio

1
cygwin: sed -i -b -e 's/FOO/BAR/g' `find . -name *.txt`-i - แก้ไข inplace ไฟล์; -b - ห้ามประมวลผล CR + LF - หากไม่มีตัวเลือกนี้ CR + LF จะถูกแปลงเป็น LF
Alexey Vishentsev

@AndrewJohnson ความคิดเห็นและข้อมูลเป็นสองสิ่งที่แตกต่างกัน
Preza8

21

ฉันรู้ว่าฉันมางานปาร์ตี้สาย ...

โดยส่วนตัวแล้วฉันชอบวิธีแก้ปัญหาที่: - http://www.dostips.com/DtipsstringManipulation.php#Snippets.Replace

นอกจากนี้เรายังใช้ฟังก์ชั่น Dedupe อย่างกว้างขวางเพื่อช่วยให้เราสามารถส่งอีเมลประมาณ 500 ฉบับต่อวันผ่าน SMTP จาก: - https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o

และสิ่งเหล่านี้ทำงานได้โดยไม่ต้องใช้เครื่องมือหรือยูทิลิตี้เพิ่มเติม

ทดแทน:

DEL New.txt
setLocal EnableDelayedExpansion
For /f "tokens=* delims= " %%a in (OLD.txt) do (
Set str=%%a
set str=!str:FOO=BAR!
echo !str!>>New.txt
)
ENDLOCAL

DEDUPLICATOR (บันทึกการใช้ -9 สำหรับหมายเลข ABA):

REM DE-DUPLICATE THE Mapping.txt FILE
REM THE DE-DUPLICATED FILE IS STORED AS new.txt

set MapFile=Mapping.txt
set ReplaceFile=New.txt

del %ReplaceFile%
::DelDupeText.bat
rem https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/sj8IUhMOq6o
setLocal EnableDelayedExpansion
for /f "tokens=1,2 delims=," %%a in (%MapFile%) do (
set str=%%a
rem Ref: http://www.dostips.com/DtTipsStringManipulation.php#Snippets.RightString
set str=!str:~-9!
set str2=%%a
set str3=%%a,%%b

find /i ^"!str!^" %MapFile%
find /i ^"!str!^" %ReplaceFile%
if errorlevel 1 echo !str3!>>%ReplaceFile%
)
ENDLOCAL

ขอบคุณ!


สคริปต์แบทช์ไม่ได้ทำอะไรนอกจากเพียงแค่การคัดลอกไฟล์ - เช่นกัน: ทำไมคุณถึงขอบคุณตัวเอง?
specializt

คำขอเดิมคือการแทนที่ "FOO" ด้วย "BAR" ในไฟล์ข้อความโดยใช้สคริปต์ชุดและด้วยฟังก์ชั่นในตัวที่ดีกว่า หากมีสิ่งใดที่ฉันขอบคุณโพสต์ของ Google Groups ฉันพบว่ามันใช้งานได้ดีมากและเราก็ยังใช้งานได้จนถึงทุกวันนี้ นอกจากนี้โปรดดูโพสต์และคำตอบเช่นนี้ว่ามีประโยชน์สำหรับผู้ใช้ที่เข้ามาตามถนนเช่นกัน ฉันไม่เห็นความคิดเห็นของคุณเกี่ยวกับการคัดลอกไฟล์ .. แน่นอนว่ามันจะนำเนื้อหาของไฟล์หนึ่งไฟล์และ echo แสดงผลลัพธ์เป็นไฟล์อื่น แต่จากข้อมูลแล้วมันตัดและแยกข้อมูลที่จำเป็นออก ฉันจะแนะนำให้ลองก่อน ;)
Leptonator

มันเป็นเครื่องมือคัดลอกไฟล์ซึ่งแทนที่สองสตริงคงที่ - คุณสามารถวางตัวแปรอย่างน้อยสองตัวในนั้นดังนั้นผู้ที่ต้องการลองใช้มันไม่จำเป็นต้องเข้าใจไวยากรณ์เพื่อที่จะสามารถใช้งานได้จริงเช่นกัน: สมมติฐานทางอินเทอร์เน็ตมักจะผิดอย่างสมบูรณ์ จำไว้.
specializt

4
@specializt - ได้โปรด ... ฉันไม่ได้มาที่นี่เพื่ออภิปรายความหมาย หากคุณต้องการเราสามารถนำออฟไลน์นี้ไปไว้ในห้องแชทได้ไหม
Leptonator

2
ในความคิดของฉันนี่คือคำตอบของคำถามเดิม ฉันจะใช้เคล็ดลับนี้เพื่อกำหนดค่าไฟล์เริ่มต้นสำหรับบริการระหว่างการติดตั้งและฉันไม่ต้องการเปิดใช้งาน PowerShell หรืออนุญาตให้โปรแกรมสคริปต์ทำงานบนเซิร์ฟเวอร์ของฉัน บ่อยครั้งที่ตอบคำถามที่เกี่ยวข้องกับ windows เริ่มต้นด้วย "ติดตั้ง gizmo นี้จากที่นั่น" เนื่องจากยังมีทัศนคติ "พีซี" อยู่
mico

15

เมื่อคุณทำงานกับGit บน Windowsแล้วก็ยิงขึ้นและการใช้งานgit-bash sedหรือเมื่อใช้ Windows 10 ให้เริ่ม "Bash บน Ubuntu บน Windows" (จากระบบย่อย Linux) และใช้งานsedและการใช้งาน

เป็นตัวแก้ไขสตรีม แต่สามารถแก้ไขไฟล์ได้โดยตรงโดยใช้คำสั่งต่อไปนี้:

sed -i -e 's/foo/bar/g' filename
  • -i ตัวเลือกที่ใช้ในการแก้ไขในชื่อไฟล์
  • -e ตัวเลือกบ่งชี้คำสั่งให้ทำงาน
    • sใช้เพื่อแทนที่นิพจน์ที่พบ "foo" ด้วย "bar" และgใช้เพื่อแทนที่การแข่งขันที่พบ

หมายเหตุโดย ereOn:

หากคุณต้องการแทนที่สตริงในไฟล์ที่มีเวอร์ชันของที่เก็บ Git เท่านั้นคุณอาจต้องการใช้:

git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'

ซึ่งทำงานสิ่งมหัศจรรย์


1
โปรดทราบว่าหากคุณกำลังทำอย่างนั้นเปลี่ยนชื่อในพื้นที่เก็บข้อมูล git และต้องการที่จะแทนที่ในไฟล์เวอร์ชั่นคุณอาจต้องทำ: git ls-files <eventual subfolders & filters> | xargs sed -i -e 's/foo/bar/g'ซึ่งทำงานได้มหัศจรรย์
ereOn

13

ฉันเล่นกับคำตอบที่มีอยู่ที่นี่และต้องการโซลูชันที่ปรับปรุงแล้วของฉัน ...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }"

หรือถ้าคุณต้องการบันทึกผลลัพธ์อีกครั้งลงในไฟล์ ...

type test.txt | powershell -Command "$input | ForEach-Object { $_ -replace \"foo\", \"bar\" }" > outputFile.txt

ประโยชน์ของการทำเช่นนี้คือคุณสามารถไปป์ที่เอาต์พุตจากโปรแกรมใดก็ได้ จะพิจารณาใช้นิพจน์ทั่วไปด้วยเช่นกัน ไม่สามารถหาวิธีทำให้เป็นไฟล์ BAT เพื่อให้ใช้งานได้ง่ายขึ้น ... :-(


3
นี่เป็นทางออกที่ดี น่าเสียดายที่การใช้typeหมายถึงมีการห่อทุกบรรทัดที่มีความยาวมากกว่า 80 อักขระ ช่างเจ็บปวดเหลือเกิน
sirdank

12

ฉันใช้ perl และทำงานได้อย่างมหัศจรรย์

perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" <fileName>

. orig เป็นส่วนขยายที่จะผนวกเข้ากับไฟล์ต้นฉบับ

สำหรับไฟล์ที่ตรงกันเช่น * .html

for %x in (<filePattern>) do perl -pi.orig -e "s/<textToReplace>/<textToReplaceWith>/g;" %x

นี้เป็นวิธีที่ง่าย +1 เมื่อมีการแปลงจากการดวลจุดโทษที่จะตีเพียงแทนที่sedด้วยperl -pi.backup -eและขอบคุณมัน :)
Yann39

11

กับ replacer.bat

1) พร้อมe?ตัวเลือกที่จะประเมินลำดับอักขระพิเศษเช่น\n\rและลำดับ Unicode ในกรณีนี้จะแทนที่คำพูด"Foo"และ"Bar":

call replacer.bat "e?C:\content.txt" "\u0022Foo\u0022" "\u0022Bar\u0022"

2) ตรงไปตรงมาเปลี่ยนที่FooและBarยังไม่ได้ยกมา

call replacer.bat "C:\content.txt" "Foo" "Bar"

มันไม่ทำงานสำหรับฉัน คุณทำงานนี้ได้อย่างไร ฉันได้รับข้อผิดพลาด 'replace_in_config.bat' ไม่ได้รับการยอมรับว่าเป็นคำสั่งภายในหรือภายนอกโปรแกรมที่ทำงานได้หรือไฟล์แบตช์
FrenkyB

@FrenkyB - จำเป็นต้องอยู่ในไดเรกทอรีเดียวกันกับที่คุณเรียกมันหรือในเส้นทาง - ss64.com/nt/path.html
npocmaka

ฉันมีสามไฟล์ในไดเรกทอรีเดียวกัน
FrenkyB

9

นี่เป็นวิธีแก้ปัญหาที่ฉันพบว่าทำงานได้บน Win XP ในไฟล์แบตช์ที่กำลังรันฉันรวมสิ่งต่อไปนี้:

set value=new_value

:: Setup initial configuration
:: I use && as the delimiter in the file because it should not exist, thereby giving me the whole line
::
echo --> Setting configuration and properties.
for /f "tokens=* delims=&&" %%a in (config\config.txt) do ( 
  call replace.bat "%%a" _KEY_ %value% config\temp.txt 
)
del config\config.txt
rename config\temp.txt config.txt

replace.batไฟล์ดังต่อไปนี้ ฉันไม่พบวิธีที่จะรวมฟังก์ชั่นนั้นในไฟล์แบทช์เดียวกันเพราะ%%aตัวแปรดูเหมือนจะให้ค่าสุดท้ายในลูป for เสมอ

replace.bat:

@echo off

:: This ensures the parameters are resolved prior to the internal variable
::
SetLocal EnableDelayedExpansion

:: Replaces Key Variables
::
:: Parameters:
:: %1  = Line to search for replacement
:: %2  = Key to replace
:: %3  = Value to replace key with
:: %4  = File in which to write the replacement
::

:: Read in line without the surrounding double quotes (use ~)
::
set line=%~1

:: Write line to specified file, replacing key (%2) with value (%3)
::
echo !line:%2=%3! >> %4

:: Restore delayed expansion
::
EndLocal

1
น่าเศร้าที่นี่ยังข้ามบรรทัดว่าง คุณลักษณะของ {สำหรับ} {} คำสั่ง
John Rocha

7

ลองดูที่จะมีประโยชน์เช่นยูทิลิตี้สำหรับ cmd.exeซึ่งถามว่าเทียบเท่า sed ภายใต้ Windows ควรใช้กับคำถามนี้เช่นกัน บทสรุปผู้บริหาร:

  • สามารถทำได้ในไฟล์แบทช์ แต่ก็ไม่สวย
  • มี executables ของบุคคลที่สามมากมายที่จะทำเพื่อคุณหากคุณมีความหรูหราในการติดตั้งหรือเพียงแค่คัดลอกไฟล์ exe
  • สามารถทำได้ด้วย VBScript หรือคล้ายกันหากคุณต้องการบางสิ่งบางอย่างสามารถทำงานบนกล่อง Windows โดยไม่ต้องดัดแปลง ฯลฯ

4

อาจจะช้าไปหน่อย แต่ฉันมักจะมองหาสิ่งที่คล้ายกันเนื่องจากฉันไม่ต้องการผ่านความเจ็บปวดในการได้รับการอนุมัติซอฟต์แวร์

อย่างไรก็ตามคุณมักจะใช้คำสั่ง FOR ในรูปแบบต่างๆ มีคนสร้างไฟล์แบตช์ที่มีประโยชน์ซึ่งทำการค้นหาและแทนที่ ได้ดูที่นี่ สิ่งสำคัญคือต้องเข้าใจข้อ จำกัด ของแบทช์ไฟล์ที่จัดเตรียมไว้ให้ ด้วยเหตุนี้ฉันไม่ได้คัดลอกซอร์สโค้ดในคำตอบนี้


4

ไฟล์แบตช์สองไฟล์ที่จัดหาsearch and replaceฟังก์ชั่นถูกเขียนโดยสมาชิก Stack Overflow dbenhamและaaciniใช้native built-in jscriptใน Windows

มีทั้งrobustและvery swift with large filesเปรียบเทียบกับการเขียนสคริปต์แบบแบตช์ธรรมดาและsimplerเพื่อใช้สำหรับการแทนที่ข้อความพื้นฐาน พวกเขาทั้งสองมีการWindows regular expressionจับคู่รูปแบบ

  1. นี้sed-likeไฟล์ชุดผู้ช่วยที่เรียกว่าrepl.bat (โดย dbenham)

    ตัวอย่างการใช้Lสวิตช์ตัวอักษร:

    echo This is FOO here|repl "FOO" "BAR" L
    echo and with a file:
    type "file.txt" |repl "FOO" "BAR" L >"newfile.txt"
    
  2. นี้grep-likeไฟล์ชุดผู้ช่วยที่เรียกว่าfindrepl.bat (โดย aacini)

    ตัวอย่างที่มีนิพจน์ทั่วไปที่ใช้งานอยู่:

    echo This is FOO here|findrepl "FOO" "BAR" 
    echo and with a file:
    type "file.txt" |findrepl "FOO" "BAR" >"newfile.txt"
    

ทั้งคู่กลายเป็นระบบสาธารณูปโภคที่มีประสิทธิภาพ when placed in a folder that is on the pathหรือสามารถใช้ในโฟลเดอร์เดียวกันกับไฟล์แบตช์หรือจากพรอมต์คำสั่ง

พวกเขาทั้งสองมีcase-insensitiveสวิตช์และฟังก์ชั่นอื่น ๆ อีกมากมาย



3

เพิ่งพบปัญหาที่คล้ายกัน - "ค้นหาและแทนที่ข้อความภายในไฟล์" แต่ด้วยข้อยกเว้นว่าทั้งชื่อไฟล์และการค้นหา / repalce ฉันต้องใช้ regex เพราะฉันไม่คุ้นเคยกับ Powershell และต้องการบันทึกการค้นหาของฉันเพื่อใช้งานในภายหลัง

ดังนั้นในขณะที่ Googling :) ฉันพบเครื่องมือที่ยอดเยี่ยม - FAR (ค้นหาและแทนที่) (ไม่ใช่ FART)

โปรแกรมเล็ก ๆ นั้นมี GUI ที่ดีและรองรับ regex สำหรับการค้นหาในชื่อไฟล์และภายในไฟล์ Disadventage เท่านั้นคือถ้าคุณต้องการบันทึกการตั้งค่าของคุณคุณต้องเรียกใช้โปรแกรมในฐานะผู้ดูแลระบบ (อย่างน้อยใน Win7)


มันเป็นคำตอบเดียวกับคำตอบจาก 2010 @VonC ในกระทู้นี้
jeb

@jeb ฉันชี้ให้เห็นว่าFARไม่ใช่FART - สองโปรแกรมที่แตกต่างกันที่มีชื่อเหมือนกันเกือบ FAR มี GUI และสามารถทำงานกับ regex ในขณะที่ความคิดเห็นด้านล่างที่คนเธรดกล่าวถึงว่า FART ไม่สนับสนุน regex
madcorp

3

ฉันชอบที่จะใช้sedจากโปรแกรมอรรถประโยชน์ GNU สำหรับ Win32ต้องมีการบันทึกดังต่อไปนี้

  • คำพูดเดียว''จะไม่ทำงานใน windows ใช้""แทน
  • sed -iจะไม่ทำงานใน windows มันจะต้องมีการแลกเปลี่ยนไฟล์

รหัสการทำงานของsedการค้นหาและแทนที่ข้อความในไฟล์ใน windows จึงเป็นดังนี้

sed -e "s/foo/bar/g" test.txt > tmp.txt && mv tmp.txt test.txt

2
ก่อนที่ผู้ใช้ Windows จะทำการสลับไฟล์ทันที: รุ่นใหม่กว่ารองรับการแก้ไขแบบแทนที่ด้วย-i! ถ้ารุ่น sed ของคุณไม่แล้วตรวจสอบคำสั่งจากคำตอบนี้: stackoverflow.com/a/33762001/2492801
Benjamin Bihler

2

นี่คือสิ่งหนึ่งที่การสร้างสคริปต์ชุดงานทำได้ไม่ดี

สคริปต์ที่เชื่อมโยงกับพริกเพิ่มเติมจะใช้งานได้กับไฟล์บางไฟล์ แต่น่าเสียดายที่สคริปต์นี้สำลักไฟล์ที่มีอักขระเช่นไพพ์และแอมเปอร์แซนด์

VBScript เป็นเครื่องมือในตัวที่ดีกว่าสำหรับงานนี้ ดูบทความนี้สำหรับตัวอย่าง: http://www.microsoft.com/technet/scriptcenter/resources/qanda/feb05/hey0208.mspx


2

@Rachel ให้คำตอบที่ดีเยี่ยม แต่นี่คือรูปแบบของการอ่านเนื้อหาให้กับ$dataตัวแปรPowerShell จากนั้นคุณสามารถจัดการเนื้อหาได้หลายครั้งก่อนที่จะเขียนไปยังไฟล์เอาต์พุต ดูวิธีการกำหนดค่าหลายบรรทัดในไฟล์แบตช์. bat

@REM ASCII=7bit ascii(no bom), UTF8=with bom marker
set cmd=^
  $old = '\$Param1\$'; ^
  $new = 'Value1'; ^
  [string[]]$data = Get-Content 'datafile.txt'; ^
  $data = $data -replace $old, $new; ^
  out-file -InputObject $data -encoding UTF8 -filepath 'datafile.txt';
powershell -NoLogo -Noninteractive -InputFormat none -Command "%cmd%"

2

ใช้ powershell ใน. bat - สำหรับ Windows 7+

การเข้ารหัส utf8 นั้นเป็นตัวเลือกซึ่งดีสำหรับเว็บไซต์

@echo off
set ffile='myfile.txt'
set fold='FOO'
set fnew='BAR'
powershell -Command "(gc %ffile%) -replace %fold%, %fnew% | Out-File %ffile% -encoding utf8"

1

ดาวน์โหลดCygwin (ฟรี) และใช้คำสั่งเหมือนยูนิกซ์ที่บรรทัดคำสั่งของ Windows

ทางออกที่ดีที่สุดของคุณ: sed


10
Cygwin นั้นชั่วร้าย อย่าติดตั้ง ควรใช้ UnixUtils ที่กล่าวถึงด้านล่าง
zedoo

24
มีอะไรเลวร้ายเกี่ยวกับเรื่องนี้?
jm

@jm อาจเป็นเพราะคุณต้องติดตั้งสิ่งทั้งหมดเข้าด้วยกันแทนที่จะใช้ไฟล์ปฏิบัติการเดียวเมื่อใดก็ตามที่คุณต้องการ
Andry

ดีกว่าการใช้ powershell มันเป็นจริงในตัวใน windows
Preza8

0

สามารถดูเครื่องมือแทนที่และแทนที่ตัวกรองได้ที่https://zoomicon.github.io/tranXform/ (รวมแหล่งที่มา) ตัวที่สองคือตัวกรอง

เครื่องมือที่ใช้แทนที่สตริงในไฟล์อยู่ใน VBScript (ต้องการ Windows Script Host [WSH] เพื่อให้ทำงานใน Windows รุ่นเก่า)

ตัวกรองอาจไม่ทำงานกับ Unicode เว้นแต่คุณจะคอมไพล์ด้วย Delphi ล่าสุด (หรือ FreePascal / Lazarus)


-5

ฉันประสบปัญหานี้หลายครั้งในขณะที่เขียนโปรแกรมภายใต้ Visual C ++ หากคุณมีคุณสามารถใช้ Visual Studio Find and Replace Utility อนุญาตให้คุณเลือกโฟลเดอร์และแทนที่เนื้อหาของไฟล์ใด ๆ ในโฟลเดอร์นั้นด้วยข้อความอื่น ๆ ที่คุณต้องการ

ภายใต้ Visual Studio: แก้ไข -> ค้นหาและแทนที่ในกล่องโต้ตอบที่เปิดอยู่ให้เลือกโฟลเดอร์ของคุณและกรอกข้อมูลลงในกล่อง "ค้นหาอะไร" และ "แทนที่ด้วย" หวังว่านี่จะเป็นประโยชน์


2
ต่อไปคำตอบของคุณไม่ได้ช่วยผู้ใช้เพราะคุณคิดว่าพวกเขากำลังใช้ซอฟต์แวร์ที่พวกเขาไม่ได้กล่าวถึง กรุณาแนะนำตัวเลือกที่ไม่ต้องใช้ซอฟต์แวร์
Aibrean

@Biban คำตอบคือไม่มีประโยชน์ แต่ไม่ใช่ด้วยเหตุผลนั้นมันเป็นจุดเริ่มต้นที่ผิด
Paul
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.