ฟีเจอร์และข้อ จำกัด ที่ไม่มีเอกสารของคำสั่ง Windows FINDSTR คืออะไร


188

คำสั่ง Windows FINDSTR ได้รับการบันทึกไว้อย่างน่ากลัว มีความช่วยเหลือบรรทัดคำสั่งพื้นฐานมากที่มีให้ผ่านFINDSTR /?หรือHELP FINDSTRแต่มันไม่เพียงพออย่างมาก มีเอกสารอีกเล็กน้อยกระจ้อยร่อยเป็นแบบออนไลน์ที่https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/findstr

มีฟีเจอร์และข้อ จำกัด มากมายของ FINDSTR ที่ไม่ได้บอกใบ้ถึงในเอกสาร และไม่สามารถคาดหวังได้หากปราศจากความรู้และ / หรือการทดลองอย่างรอบคอบ

ดังนั้นคำถามคือ - ฟีเจอร์และข้อ จำกัด FINDSTR ที่ไม่มีเอกสารใด ๆ

วัตถุประสงค์ของคำถามนี้คือการจัดเก็บที่เก็บครบวงจรของคุณสมบัติที่ไม่มีเอกสารจำนวนมากดังนั้น:

A) นักพัฒนาสามารถใช้ประโยชน์จากคุณสมบัติที่มี

B) นักพัฒนาไม่ต้องเสียเวลากับการสงสัยว่าทำไมบางสิ่งบางอย่างไม่ทำงานเมื่อมันดูเหมือนว่าควร

โปรดตรวจสอบให้แน่ใจว่าคุณทราบเอกสารที่มีอยู่แล้วก่อนตอบกลับ หากข้อมูลนั้นได้รับความคุ้มครองโดยความช่วยเหลือแสดงว่าข้อมูลนั้นไม่ได้อยู่ที่นี่

ที่นี่ไม่ใช่ที่สำหรับแสดงการใช้ FINDSTR ที่น่าสนใจ หากบุคคลที่มีเหตุผลสามารถคาดการณ์พฤติกรรมของการใช้งานเฉพาะของ FINDSTR ตามเอกสารนั่นแสดงว่ามันไม่ได้อยู่ที่นี่

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


15
หรืออีกวิธีหนึ่งคุณสามารถทิ้งยูทิลิตี้ MS ที่ไม่มีเอกสารเส็งเคร็งทั้งหมดและติดตั้ง / ใช้grepซึ่งเป็นที่เข้าใจและจัดทำเอกสารเป็นอย่างดี :-) ดูstackoverflow.com/questions/2635740/เป็นต้น
paxdiablo

17
โดยทั้งหมดหากคุณอยู่ในตำแหน่งที่จะใช้สิ่งอื่นที่ไม่ใช่ FINDSTR นั่นก็คือคำแนะนำที่ดี แต่บางคนอยู่ในสภาพแวดล้อมที่ห้ามมิให้มีการสาธารณูปโภค
dbenham

4
ไม่มีการกระทำความผิด ฉันพิจารณาอย่างจริงจังว่าด้วยการปฏิเสธความรับผิดชอบ FINDSTR ของฉันเองซึ่งคล้ายกับความคิดเห็นของคุณ! :)
dbenham

41
ฉันตกใจและผิดหวังกับใครบางคนจะพบคำถามนี้ "ไม่สร้างสรรค์" และลงคะแนนให้ปิด ความคิดจำนวนมากเข้าไปในคำถามโดยเฉพาะเพื่อหลีกเลี่ยง "ความเห็นการอภิปรายข้อโต้แย้งการหยั่งเสียงหรือการอภิปรายเพิ่มเติม" คำถามถูกโพสต์เป็นเวลา 3.5 เดือนและไม่มีการอ้างถึงเชิงลบใด ๆ ที่เกิดขึ้น คำตอบที่จับคู่เต็มไปด้วยข้อเท็จจริงและต้องใช้เวลาหลายชั่วโมงในการวิจัยและการทดลองอย่างระมัดระวัง
dbenham

6
ผู้อ่านบางคนอาจสนใจบริบททางประวัติศาสตร์ของคำสั่ง findstr: blogs.msdn.com/b/oldnewthing/archive/2012/11/28/10372436.aspx
Harry Johnston

คำตอบ:


279

คำนำข้อมูล
ส่วนใหญ่ในคำตอบนี้ได้รับการรวบรวมจากการทดลองที่ทำงานบนเครื่อง Vista เว้นแต่จะระบุไว้อย่างชัดเจนเป็นอย่างอื่นฉันไม่ได้รับการยืนยันว่าข้อมูลนี้ใช้กับ Windows รุ่นอื่นหรือไม่

เอาท์พุท FINDSTR
เอกสารไม่เคยรบกวนการอธิบายเอาท์พุทของ FINDSTR มันแสดงถึงความจริงที่ว่ามีการพิมพ์บรรทัดที่ตรงกัน แต่ไม่มีอะไรเพิ่มเติม

รูปแบบของการจับคู่สายเอาท์พุทเป็นดังนี้:

ชื่อไฟล์: LINENUMBER: lineOffset: ข้อความ

ที่ไหน

fileName: = ชื่อของไฟล์ที่มีบรรทัดที่ตรงกัน ชื่อไฟล์จะไม่ถูกพิมพ์หากมีการร้องขออย่างชัดเจนสำหรับไฟล์เดียวหรือหากค้นหาการป้อนข้อมูล piped หรือการเปลี่ยนเส้นทางการป้อนข้อมูล เมื่อพิมพ์ชื่อไฟล์จะรวมข้อมูลเส้นทางใด ๆ ที่ให้ไว้เสมอ ข้อมูลเส้นทางเพิ่มเติมจะถูกเพิ่มหาก/Sมีการใช้ตัวเลือก เส้นทางที่พิมพ์จะสัมพันธ์กับเส้นทางที่ให้ไว้เสมอหรือสัมพันธ์กับไดเรกทอรีปัจจุบันหากไม่ได้ระบุไว้

หมายเหตุ - คำนำหน้าชื่อไฟล์ที่สามารถหลีกเลี่ยงได้เมื่อค้นหาไฟล์หลายไฟล์โดยใช้ที่ไม่ได้มาตรฐาน (และไม่ดีเอกสาร) สัญลักษณ์ และ< >กฎระเบียบที่แน่นอนสำหรับวิธีการเหล่านี้ทำงานสัญลักษณ์สามารถพบได้ที่นี่ สุดท้ายคุณก็สามารถดูที่นี้เป็นตัวอย่างของวิธีการที่สัญลักษณ์ที่ไม่ได้มาตรฐานทำงานกับ findstr

lineNumber: = หมายเลขบรรทัดของบรรทัดที่ตรงกันที่แสดงเป็นค่าทศนิยมโดยที่ 1 หมายถึงบรรทัดที่ 1 ของอินพุต พิมพ์เฉพาะในกรณี/Nที่ระบุตัวเลือก

lineOffset: = ออฟเซตทศนิยมไบต์ของการเริ่มต้นของบรรทัดที่ตรงกันโดยมี 0 แทนอักขระ 1 ของบรรทัดที่ 1 พิมพ์เฉพาะในกรณี/Oที่ระบุตัวเลือก นี่ไม่ใช่ออฟเซ็ตของการแข่งขันภายในเส้น มันคือจำนวนไบต์จากจุดเริ่มต้นของไฟล์ถึงจุดเริ่มต้นของบรรทัด

text = การแทนค่าไบนารีของบรรทัดที่ตรงกันรวมถึง <CR> และ / หรือ <LF> ไม่มีสิ่งใดเหลืออยู่จากเอาต์พุตไบนารีเช่นตัวอย่างนี้ที่ตรงกับทุกบรรทัดจะสร้างสำเนาไบนารีที่แน่นอนของไฟล์ต้นฉบับ

FINDSTR "^" FILE >FILE_COPY

ตัวเลือก / A ตั้งค่าสีของ fileName :, lineNumber :, และ lineOffset: output เท่านั้น ข้อความของบรรทัดที่ตรงกันจะถูกเอาต์พุตด้วยสีคอนโซลปัจจุบันเสมอ ตัวเลือก / A มีผลเฉพาะเมื่อมีการแสดงผลเอาต์พุตโดยตรงไปยังคอนโซล ตัวเลือก / A ไม่มีผลใด ๆ หากผลลัพธ์ถูกเปลี่ยนเส้นทางไปยังไฟล์หรือ piped ดู2018-08-18 แก้ไขในคำตอบของ Aaciniสำหรับคำอธิบายเกี่ยวกับพฤติกรรมบั๊กกี้เมื่อเอาต์พุตถูกเปลี่ยนเส้นทางไปยัง CON

อักขระควบคุมส่วนใหญ่และอักขระ ASCII แบบขยายส่วนใหญ่แสดงเป็นจุดบน XP
FINDSTR บน XP แสดงอักขระควบคุมส่วนใหญ่ที่ไม่สามารถพิมพ์ได้จากบรรทัดที่ตรงกันเป็นจุด (จุด) บนหน้าจอ อักขระควบคุมต่อไปนี้เป็นข้อยกเว้น พวกเขาแสดงเป็นตัวเอง: แท็บ 0x09, 0x0A LineFeed, แท็บแนวตั้ง 0x0B, ฟีดฟอร์ม 0x0C, 0x0D Carriage Return

XP FINDSTR ยังแปลงอักขระ ASCII เพิ่มเติมจำนวนหนึ่งให้เป็นจุดเช่นกัน อักขระ ASCII แบบขยายที่แสดงเป็นจุดบน XP จะเหมือนกับอักขระที่ถูกแปลงเมื่อมีให้ในบรรทัดคำสั่ง ดูส่วน"ข้อ จำกัด อักขระสำหรับพารามิเตอร์บรรทัดคำสั่ง - การแปลง ASCII เพิ่มเติม"ในภายหลังในบทความนี้

อักขระควบคุมและ ASCII ที่ขยายเพิ่มจะไม่ถูกแปลงเป็นจุดบน XP หากเอาต์พุตถูกไพพ์, เปลี่ยนเส้นทางไปยังไฟล์หรือภายในข้อ FOR IN ()

Vista และ Windows 7 จะแสดงตัวละครทุกตัวเสมอไม่เป็นจุด

รหัสส่งคืน (ERRORLEVEL)

  • 0 (สำเร็จ)
    • พบข้อมูลที่ตรงกันในอย่างน้อยหนึ่งบรรทัดอย่างน้อยหนึ่งไฟล์
  • 1 (ล้มเหลว)
    • ไม่พบข้อมูลที่ตรงกันในไฟล์ใด ๆ
    • ระบุสีไม่ถูกต้องตาม/A:xxตัวเลือก
  • 2 (ข้อผิดพลาด)
    • ตัวเลือกที่เข้ากันไม่ได้/Lและ/Rทั้งสองระบุไว้
    • ไม่มีอาร์กิวเมนต์หลัง/A:, /F:, /C:, /D:หรือ/G:
    • ไฟล์ที่ระบุโดย/F:fileหรือ/G:fileไม่พบ
  • 255 (ข้อผิดพลาด)

แหล่งข้อมูลที่จะค้นหา (อัปเดตตามการทดสอบกับ Windows 7)
Findstr สามารถค้นหาข้อมูลจากแหล่งใดแหล่งหนึ่งต่อไปนี้:

  • ชื่อไฟล์ที่ระบุเป็นอาร์กิวเมนต์และ / หรือใช้/F:fileตัวเลือก

  • stdin ผ่านการเปลี่ยนเส้นทาง findstr "searchString" <file

  • สตรีมข้อมูลจากไปป์ type file | findstr "searchString"

อาร์กิวเมนต์ / ตัวเลือกมีความสำคัญเหนือกว่าการเปลี่ยนเส้นทางซึ่งจะมีความสำคัญเหนือกว่าข้อมูลที่ถูกวางท่อ

อาร์กิวเมนต์ชื่อไฟล์และ/F:fileอาจรวมกัน อาจใช้อาร์กิวเมนต์ชื่อไฟล์หลายรายการ หาก/F:fileระบุหลายตัวเลือกจะใช้ตัวเลือกสุดท้ายเท่านั้น อนุญาตให้ใช้ไวลด์การ์ดในการโต้แย้งชื่อไฟล์ แต่ไม่สามารถอยู่ในไฟล์ที่ระบุ/F:fileได้

แหล่งที่มาของสตริงการค้นหา (Updated จากการทดสอบกับ Windows 7)และตัวเลือกอาจจะรวม อาจระบุหลายตัวเลือก หากระบุหลายตัวเลือกจะใช้ตัวเลือกสุดท้ายเท่านั้น หากทั้งสองหรือถูกใช้แล้วทุกข้อโต้แย้งที่ไม่ใช่ตัวเลือกจะถือว่าเป็นไฟล์ที่จะค้นหา หากค่ามิได้ถูกนำมาใช้แล้วอาร์กิวเมนต์ที่ไม่ใช่ตัวเลือกแรกที่จะถือว่าเป็นพื้นที่ที่คั่นรายการคำค้นหา
/G:file/C:string/C:string/G:file/G:file/C:string/G:file/C:string

ชื่อไฟล์จะต้องไม่ถูกยกมาภายในไฟล์เมื่อใช้/F:FILEตัวเลือก
ชื่อไฟล์อาจมีช่องว่างและอักขระพิเศษอื่น ๆ คำสั่งส่วนใหญ่ต้องการให้อ้างชื่อไฟล์ดังกล่าว แต่/F:files.txtตัวเลือกFINDSTR จะต้องไม่ระบุชื่อไฟล์ใน files.txt ไฟล์จะไม่ถูกค้นพบถ้าชื่อถูกยกมา

BUG - ชื่อไฟล์ย่อ 8.3 สามารถแบ่ง/Dและ/Sตัวเลือก
เช่นเดียวกับคำสั่ง Windows ทั้งหมด FINDSTR จะพยายามจับคู่ทั้งชื่อยาวและชื่อ 8.3 สั้นเมื่อค้นหาไฟล์ที่จะค้นหา สมมติว่าโฟลเดอร์ปัจจุบันมีไฟล์ที่ไม่ว่างเปล่าดังต่อไปนี้:

b1.txt
b.txt2
c.txt

คำสั่งต่อไปนี้จะค้นหาไฟล์ทั้ง 3 ไฟล์ได้สำเร็จ:

findstr /m "^" *.txt

b.txt2จับคู่เนื่องจากชื่อย่อB9F64~1.TXTตรงกันตรงกัน สิ่งนี้สอดคล้องกับพฤติกรรมของคำสั่ง Windows อื่น ๆ ทั้งหมด

แต่ข้อผิดพลาดที่มี/Dและ/Sตัวเลือกทำให้คำสั่งต่อไปนี้เพื่อค้นหาเท่านั้นb1.txt

findstr /m /d:. "^" *.txt
findstr /m /s "^" *.txt

ข้อผิดพลาดป้องกันb.txt2การถูกพบเช่นเดียวกับชื่อไฟล์ทั้งหมดที่เรียงลำดับb.txt2ภายในไดเรกทอรีเดียวกัน แฟ้มเพิ่มเติมว่าการเรียงลำดับก่อนเช่นa.txtจะพบ ไฟล์เพิ่มเติมที่เรียงลำดับในภายหลังเช่นd.txtจะหายไปเมื่อเกิดข้อผิดพลาดขึ้น

แต่ละไดเรกทอรีที่ค้นหาจะได้รับการปฏิบัติอย่างอิสระ ตัวอย่างเช่น/Sตัวเลือกจะเริ่มค้นหาในโฟลเดอร์ลูกได้สำเร็จหลังจากล้มเหลวในการค้นหาไฟล์ในพาเรนต์ แต่เมื่อเกิดข้อผิดพลาดทำให้พลาดชื่อไฟล์สั้น ๆ ในชายด์ดังนั้นไฟล์ที่ตามมาทั้งหมดในโฟลเดอร์ลูกก็จะหายไปเช่นกัน .

คำสั่งทำงานบั๊กได้ฟรีหากสร้างชื่อไฟล์เดียวกันบนเครื่องที่ปิดใช้งานการสร้างชื่อ NTFS 8.3 แน่นอนb.txt2จะไม่ได้พบ แต่c.txtจะพบได้อย่างถูกต้อง

ไม่ใช่ชื่อย่อทั้งหมดที่ก่อให้เกิดข้อผิดพลาด อินสแตนซ์ทั้งหมดของพฤติกรรมบั๊กที่ฉันได้เห็นเกี่ยวข้องกับส่วนขยายที่มีความยาวมากกว่า 3 อักขระโดยมีชื่อสั้น ๆ 8.3 ที่เริ่มต้นเหมือนกับชื่อปกติที่ไม่ต้องการชื่อ 8.3

ข้อผิดพลาดได้รับการยืนยันใน XP, Vista และ Windows 7

อักขระที่ไม่สามารถพิมพ์ได้และ/Pตัวเลือกตัวเลือก
นี้/Pทำให้ FINDSTR ข้ามไฟล์ใด ๆ ที่มีรหัสไบต์ทศนิยมต่อไปนี้:
0-7, 14-25, 27-31

อีกวิธีหนึ่ง/Pตัวเลือกจะข้ามไฟล์ที่มีอักขระควบคุมที่ไม่สามารถพิมพ์ได้เท่านั้น อักขระควบคุมคือรหัสที่น้อยกว่าหรือเท่ากับ 31 (0x1F) FINDSTR ถือว่าตัวควบคุมต่อไปนี้เป็นพิมพ์ได้:

 8  0x08  backspace
 9  0x09  horizontal tab
10  0x0A  line feed
11  0x0B  vertical tab
12  0x0C  form feed
13  0x0D  carriage return
26  0x1A  substitute (end of text)

อักขระควบคุมอื่น ๆ ทั้งหมดจะถือว่าไม่สามารถพิมพ์ได้การมีอยู่ของ/Pตัวเลือกทำให้ข้ามไฟล์

การป้อนข้อมูล Piped และ Redirected อาจ<CR><LF>ต่อท้าย
หากมีการป้อนข้อมูลไปป์<LF>ไลน์และอักขระตัวสุดท้ายของกระแสไม่ได้FINDSTR จะผนวก<CR><LF>เข้ากับอินพุตโดยอัตโนมัติ สิ่งนี้ได้รับการยืนยันใน XP, Vista และ Windows 7 (ฉันเคยคิดว่าไพพ์ของ Windows มีหน้าที่ในการปรับเปลี่ยนอินพุต แต่ตั้งแต่ฉันค้นพบว่า FINDSTR กำลังทำการแก้ไขจริง)

เช่นเดียวกับการป้อนข้อมูลที่เปลี่ยนเส้นทางบน Vista หากอักขระตัวสุดท้ายของไฟล์ที่ใช้เป็นอินพุตที่ถูกเปลี่ยนเส้นทางไม่ได้<LF>FINDSTR จะผนวก<CR><LF>เข้ากับอินพุตโดยอัตโนมัติ อย่างไรก็ตาม XP และ Windows 7 จะไม่เปลี่ยนอินพุตที่เปลี่ยนเส้นทาง

FINDSTR แฮงค์บน XP และ Windows 7 หากอินพุตที่เปลี่ยนเส้นทางไม่ได้จบด้วย<LF>
นี่คือ "คุณสมบัติ" ที่น่ารังเกียจใน XP และ Windows 7 หากอักขระตัวสุดท้ายของไฟล์ที่ใช้เป็นอินพุตที่เปลี่ยนเส้นทางไม่ได้จบลงด้วย<LF>FINDSTR จะหยุดทำงานทันที ถึงจุดสิ้นสุดของไฟล์ที่ถูกเปลี่ยนเส้นทาง

บรรทัดสุดท้ายของข้อมูล Piped อาจถูกละเว้นหากประกอบด้วยอักขระเดียว
หากอินพุตถูก<LF>ไพพ์และบรรทัดสุดท้ายประกอบด้วยอักขระเดียวที่ไม่ได้ตามด้วยดังนั้น FINDSTR จะละเว้นบรรทัดสุดท้ายอย่างสมบูรณ์

ตัวอย่าง - คำสั่งแรกที่มีอักขระเดียวและไม่มีความ<LF>ล้มเหลวในการจับคู่ แต่คำสั่งที่สองที่มี 2 ตัวอักษรทำงานได้ดีเช่นเดียวกับคำสั่งที่สามที่มีหนึ่งอักขระที่มีการยกเลิกการขึ้นบรรทัดใหม่

> set /p "=x" <nul | findstr "^"

> set /p "=xx" <nul | findstr "^"
xx

> echo x| findstr "^"
x

รายงานโดยใช้ฟองน้ำ DosTips ท้องในข้อผิดพลาด findstr ใหม่ ยืนยันใน XP, Windows 7 และ Windows 8 ยังไม่เคยได้ยินเกี่ยวกับ Vista (ฉันไม่มี Vista ที่จะทดสอบอีกต่อไป)

ตัวเลือกไวยากรณ์
ตัวเลือกที่สามารถนำหน้าด้วยอย่างใดอย่างหนึ่ง/หรือ- ตัวเลือกอาจจะถูกตัดแบ่งหลังเดียวหรือ/ -อย่างไรก็ตามรายการตัวเลือกที่ต่อกันอาจมีตัวเลือกหลายตัวเลือกได้ไม่เกินหนึ่งตัวเช่น OFF หรือ F: และตัวเลือกหลายตัวจะต้องเป็นตัวเลือกสุดท้ายในรายการ

ต่อไปนี้เป็นวิธีที่เทียบเท่าทั้งหมดในการแสดงการค้นหา regex ที่ไม่สนใจขนาดตัวพิมพ์สำหรับบรรทัดใด ๆ ที่มีทั้ง "hello" และ "goodbye" ในลำดับใด ๆ

  • /i /r /c:"hello.*goodbye" /c:"goodbye.*hello"

  • -i -r -c:"hello.*goodbye" /c:"goodbye.*hello"

  • /irc:"hello.*goodbye" /c:"goodbye.*hello"

ขีดจำกัดความยาวของสตริงการค้นหา
ใน Vista ความยาวสูงสุดที่อนุญาตสำหรับสตริงการค้นหาเดียวคือ 511 ไบต์ หากสตริงการค้นหาใด ๆ เกิน 511 ผลลัพธ์จะเป็นFINDSTR: Search string too long.ข้อผิดพลาดกับ ERRORLEVEL 2

เมื่อทำการค้นหานิพจน์ทั่วไปความยาวสตริงการค้นหาสูงสุดคือ 254 นิพจน์ทั่วไปที่มีความยาวระหว่าง 255 และ 511 จะส่งผลให้เกิดFINDSTR: Out of memoryข้อผิดพลาดกับ ERRORLEVEL 2 ความยาวนิพจน์ปกติ> 511 ส่งผลให้เกิดFINDSTR: Search string too long.ข้อผิดพลาด

ใน Windows XP ความยาวสตริงการค้นหานั้นสั้นลงอย่างเห็นได้ชัด ข้อผิดพลาด Findstr: "ค้นหาสตริงยาวเกินไป": วิธีแยกและจับคู่สตริงย่อยใน "สำหรับ" วนซ้ำ ขีด จำกัด XP คือ 127 ไบต์สำหรับการค้นหาทั้งตัวอักษรและ regex

ขีดจำกัดความยาวบรรทัด
ไฟล์ที่ระบุเป็นอาร์กิวเมนต์บรรทัดคำสั่งหรือผ่านตัวเลือก / F: FILE ไม่มีขีดจำกัดความยาวบรรทัดที่ทราบ การค้นหาถูกเรียกใช้กับไฟล์ 128MB ที่ไม่มี <LF> เดียว

ข้อมูลที่ถูกวางท่อและอินพุตที่ถูกเปลี่ยนเส้นทางถูก จำกัด ที่ 8191 ไบต์ต่อบรรทัด ขีด จำกัด นี้เป็น "คุณสมบัติ" ของ FINDSTR ไม่ได้มีอยู่ในไพพ์หรือการเปลี่ยนเส้นทาง FINDSTR โดยใช้ stdin ที่ถูกเปลี่ยนเส้นทางหรืออินพุต piped จะไม่ตรงกับบรรทัดใด ๆ ที่> = 8k ไบต์ Lines> = 8k สร้างข้อความแสดงข้อผิดพลาดถึง stderr แต่ ERRORLEVEL ยังคงเป็น 0 หากพบสตริงการค้นหาในอย่างน้อยหนึ่งบรรทัดที่มีอย่างน้อยหนึ่งไฟล์

ประเภทการค้นหาเริ่มต้น: ตัวอักษรเทียบกับนิพจน์ปกติ
/C:"string" - ค่าเริ่มต้นคือ / L ตัวอักษร การรวมตัวเลือก / L อย่างชัดเจนกับ / C: "string" ใช้งานได้อย่างแน่นอน แต่ซ้ำซ้อน

"string argument"- ค่าเริ่มต้นขึ้นอยู่กับเนื้อหาของสตริงการค้นหาแรก (โปรดจำไว้ว่า <space> ใช้เพื่อกำหนดขอบเขตของสตริงการค้นหา)หากสตริงการค้นหาแรกเป็นนิพจน์ทั่วไปที่ถูกต้องซึ่งมีเมตาอักขระอย่างน้อยหนึ่งตัวที่ไม่ได้ใช้ Escape สตริงการค้นหาทั้งหมดจะถือว่าเป็นนิพจน์ทั่วไป มิฉะนั้นสตริงการค้นหาทั้งหมดจะถือว่าเป็นตัวอักษร ตัวอย่างเช่น"51.4 200"จะถือว่าเป็นนิพจน์ทั่วไปสองรายการเนื่องจากสตริงแรกมีจุดที่ไม่ได้ Escape ขณะที่"200 51.4"จะถือว่าเป็นสองตัวอักษรเนื่องจากสตริงแรกไม่มีอักขระเมตาใด ๆ

/G:file- ค่าเริ่มต้นขึ้นอยู่กับเนื้อหาของบรรทัดแรกที่ไม่ว่างในไฟล์ หากสตริงการค้นหาแรกเป็นนิพจน์ทั่วไปที่ถูกต้องที่มีอย่างน้อยหนึ่งตัวอักษรเมตาไม่รอดหนีจากนั้นสตริงการค้นหาทั้งหมดจะถือว่าเป็นนิพจน์ปกติ มิฉะนั้นสตริงการค้นหาทั้งหมดจะถือว่าเป็นตัวอักษร

คำแนะนำ - เสมอชัดเจนระบุ/Lตัวเลือกตัวอักษรหรือ/Rตัวเลือกการแสดงผลปกติเมื่อใช้หรือ"string argument"/G:file

BUG - การระบุสตริงการค้นหาตัวอักษรหลายตัวสามารถให้ผลลัพธ์ที่ไม่น่าเชื่อถือ

ตัวอย่าง FINDSTR ง่าย ๆ ต่อไปนี้ล้มเหลวในการค้นหาคู่ที่ตรงกันแม้ว่าควร

echo ffffaaa|findstr /l "ffffaaa faffaffddd"

ข้อผิดพลาดนี้ได้รับการยืนยันใน Windows Server 2003, Windows XP, Vista และ Windows 7

จากการทดลอง FINDSTR อาจล้มเหลวหากตรงตามเงื่อนไขต่อไปนี้ทั้งหมด:

  • การค้นหาใช้สตริงการค้นหาตัวอักษรหลายรายการ
  • สตริงการค้นหามีความยาวต่างกัน
  • สตริงการค้นหาแบบสั้นมีการทับซ้อนจำนวนหนึ่งกับสตริงการค้นหาที่ยาวกว่า
  • การค้นหาเป็นตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ (ไม่มี/Iตัวเลือก)

ในความล้มเหลวทุกครั้งที่ฉันเห็นมันเป็นหนึ่งในสตริงการค้นหาที่สั้นกว่าที่ล้มเหลว

สำหรับข้อมูลเพิ่มเติมดูเหตุใดจึงไม่ตัวอย่าง FINDSTR ที่มีสตริงการค้นหาตามตัวอักษรหลายตัวค้นหาการจับคู่

เครื่องหมายคำพูดและแบ็คลาห์ภายในอาร์กิวเมนต์บรรทัดคำสั่ง
หมายเหตุ - ความคิดเห็นของผู้ใช้ MC ND สะท้อนให้เห็นถึงกฎที่ซับซ้อนอย่างน่ากลัวสำหรับส่วนนี้ มี 3 ขั้นตอนในการแยกวิเคราะห์ที่แตกต่างกันที่เกี่ยวข้อง:

  • cmd.exe แรกอาจต้องใช้เครื่องหมายคำพูดเพื่อหนีเป็น ^ "(ไม่มีส่วนเกี่ยวข้องกับ FINDSTR)
  • ถัดไป FINDSTR ใช้ตัวแยกวิเคราะห์อาร์กิวเมนต์ C / C ++ 2008 ก่อนซึ่งมีกฎพิเศษสำหรับ "และ \
  • หลังจากตัวแยกวิเคราะห์อาร์กิวเมนต์เสร็จสิ้นแล้ว FINDSTR จะปฏิบัติต่อ \ ตามด้วยอักขระตัวอักษรและตัวเลขเป็นตัวอักษร แต่ \ ตามด้วยอักขระที่ไม่ใช่ตัวเลขและตัวอักษรเป็นอักขระยกเว้น

ส่วนที่เหลือของส่วนที่ไฮไลต์นี้ไม่ถูกต้อง 100% มันสามารถใช้เป็นแนวทางสำหรับสถานการณ์ต่าง ๆ แต่กฎข้างต้นจำเป็นสำหรับการทำความเข้าใจทั้งหมด

หนีอ้างภายในค้นหาบรรทัดคำสั่งสตริง
คำคมภายในสตริงการค้นหาบรรทัดคำสั่งจะต้องหนีด้วย backslash \"เช่น สิ่งนี้เป็นจริงสำหรับสตริงการค้นหาทั้งตัวอักษรและ regex ข้อมูลนี้ได้รับการยืนยันใน XP, Vista และ Windows 7

หมายเหตุ: อาจต้องใช้เครื่องหมายคำพูดเพื่อหลีกเลี่ยงการแยกวิเคราะห์ CMD.EXE แต่สิ่งนี้ไม่เกี่ยวกับ FINDSTR ตัวอย่างเช่นในการค้นหาคำพูดเดียวคุณสามารถใช้:

FINDSTR \^" file && echo found || echo not found

หนีทับขวาภายในบรรทัดคำสั่งค้นหาตัวอักษรสตริง
ทับขวาในสตริงการค้นหาตัวอักษรสามารถปกติจะแสดงเป็น หรือเป็น\ \\พวกเขามักจะเทียบเท่า (อาจมีกรณีที่ผิดปกติใน Vista ที่ทับขวาจะต้องหนีออกมา แต่ผมไม่ได้มีเครื่อง Vista เพื่อทดสอบ)

แต่มีบางกรณีพิเศษ:

เมื่อค้นหาเครื่องหมายแบ็กสแลชต่อเนื่องทั้งหมดจะต้องรอด แบ็กสแลชสุดท้ายอาจถูกเลือกให้เลือก

  • \\สามารถเขียนโค้ดเป็น\\\หรือ\\\\
  • \\\สามารถเขียนโค้ดเป็น\\\\\หรือ\\\\\\

ค้นหาเครื่องหมายแบ็กสแลชหนึ่งรายการหรือมากกว่าก่อนที่คำพูดจะแปลกประหลาด ลอจิกจะแนะนำว่าต้องอ้างคำพูดให้พ้นและเครื่องหมายแบ็กสแลชชั้นนำแต่ละอันจะต้องได้รับการหลบหนี แต่สิ่งนี้ไม่ได้ผล! แต่แบ็กสแลชที่นำหน้าแต่ละครั้งจะต้องได้รับการยกเว้นสองครั้งและเครื่องหมายคำพูดจะถูกยกเว้นตามปกติ:

  • \" จะต้องมีรหัสเป็น \\\\\"
  • \\" จะต้องมีรหัสเป็น \\\\\\\\\"

ตามที่ระบุไว้ก่อนหน้านี้หนึ่งคำพูดหรือมากกว่านั้นอาจต้องมีการหลบหนีด้วย^สำหรับตัวแยกวิเคราะห์ CMD

ข้อมูลในส่วนนี้ได้รับการยืนยันใน XP และ Windows 7

การหลบหลีก Backslash ภายในสตริงคำสั่งการค้นหา regex

  • Vista เท่านั้น:แบ็กสแลชใน regex จะต้องมีการหลบหนีสองครั้งเช่นเดียว\\\\หรืออื่น ๆ ที่หลบหนีภายในชุดชั้นตัวละครเช่น [\\]

  • XP และ Windows 7:ทับขวาใน regex [\\]เสมอสามารถแสดงเป็น \\มันสามารถปกติจะแสดงเป็น แต่สิ่งนี้จะไม่ทำงานหากแบ็กสแลชนำหน้าคำพูดที่หลบหนี

    แบ็กสแลชหนึ่งรายการหรือมากกว่าก่อนที่จะอ้างคำพูดที่ต้องหลีกเลี่ยงต้องมีการหลบหนีอย่างใดอย่างหนึ่งหรือรหัสอื่นเป็น [\\]

    • \"อาจมีรหัสเป็น\\\\\"หรือ[\\]\"
    • \\"อาจมีรหัสเป็น\\\\\\\\\"หรือ[\\][\\]\"หรือ\\[\\]\"

การ
หลีกเลี่ยงการอ้างและแบ็กสแลชภายใน / G: สตริงการค้นหาตัวอักษรคำพูดแบบสแตนด์อโลนและแบ็กสแลชภายในไฟล์สตริงการค้นหาตัวอักษรที่ระบุโดยไฟล์ / G: ไม่จำเป็นต้องหลบหนี แต่สามารถเป็นได้

"และ\"เทียบเท่า

\และ\\เทียบเท่า

หากเจตนาคือการหา \\ อย่างน้อยต้องมีเครื่องหมายแบคสแลชนำหน้า ทั้งงาน\\\และ\\\\

หากเจตนาคือการหา \ "อย่างน้อยแบ็กสแลชชั้นนำจะต้องถูกหลบหนีทั้งคู่\\"และ\\\"ทำงาน

Escaping Quote และ Backslash ภายใน / G: FILE regex สตริงการค้นหา
นี่เป็นกรณีหนึ่งที่ escape sequences ทำงานตามที่คาดไว้ตามเอกสาร การอ้างอิงไม่ใช่ตัวบ่งชี้ regex ดังนั้นจึงไม่จำเป็นต้องหลีกเลี่ยง (แต่อาจเป็นได้) Backslash เป็นตัวบ่งชี้ regex ดังนั้นจะต้องมีการหลบหนี

ข้อ จำกัด อักขระสำหรับพารามิเตอร์บรรทัดคำสั่ง - การแปลง ASCII แบบขยายอักขระ
null (0x00) ไม่สามารถปรากฏในสตริงใด ๆ ในบรรทัดคำสั่ง อักขระไบต์เดียวอื่น ๆ สามารถปรากฏในสตริง (0x01 - 0xFF) อย่างไรก็ตาม FINDSTR แปลงอักขระ ASCII แบบขยายจำนวนมากที่พบภายในพารามิเตอร์บรรทัดคำสั่งเป็นอักขระอื่น สิ่งนี้มีผลกระทบที่สำคัญในสองวิธี:

1) อักขระ ASCII แบบขยายจำนวนมากจะไม่ตรงกันถ้าใช้เป็นสตริงการค้นหาในบรรทัดคำสั่ง ข้อ จำกัด นี้จะเหมือนกันสำหรับการค้นหาตามตัวอักษรและ regex หากสตริงการค้นหาต้องมี ASCII แบบขยายดังนั้น/G:FILEควรใช้ตัวเลือกแทน

2) FINDSTR อาจล้มเหลวในการค้นหาไฟล์หากชื่อมีอักขระ ASCII เพิ่มเติมและชื่อไฟล์ถูกระบุในบรรทัดคำสั่ง หากไฟล์ที่จะค้นหามี ASCII แบบขยายในชื่อ/F:FILEควรใช้ตัวเลือกแทน

นี่คือรายการที่สมบูรณ์ของการแปลงอักขระ ASCII แบบขยายที่ FINDSTR ดำเนินการกับสตริงบรรทัดคำสั่ง ตัวละครแต่ละตัวจะแสดงเป็นค่ารหัสไบต์ทศนิยม รหัสแรกหมายถึงตัวละครที่ให้มาในบรรทัดคำสั่งและรหัสที่สองหมายถึงตัวละครที่ถูกเปลี่ยนเป็น หมายเหตุ - รายการนี้ถูกรวบรวมในเครื่องของสหรัฐอเมริกา ฉันไม่ทราบว่าอาจมีผลกระทบต่อภาษาอื่นในรายการนี้

158 treated as 080     199 treated as 221     226 treated as 071
169 treated as 170     200 treated as 043     227 treated as 112
176 treated as 221     201 treated as 043     228 treated as 083
177 treated as 221     202 treated as 045     229 treated as 115
178 treated as 221     203 treated as 045     231 treated as 116
179 treated as 221     204 treated as 221     232 treated as 070
180 treated as 221     205 treated as 045     233 treated as 084
181 treated as 221     206 treated as 043     234 treated as 079
182 treated as 221     207 treated as 045     235 treated as 100
183 treated as 043     208 treated as 045     236 treated as 056
184 treated as 043     209 treated as 045     237 treated as 102
185 treated as 221     210 treated as 045     238 treated as 101
186 treated as 221     211 treated as 043     239 treated as 110
187 treated as 043     212 treated as 043     240 treated as 061
188 treated as 043     213 treated as 043     242 treated as 061
189 treated as 043     214 treated as 043     243 treated as 061
190 treated as 043     215 treated as 043     244 treated as 040
191 treated as 043     216 treated as 043     245 treated as 041
192 treated as 043     217 treated as 043     247 treated as 126
193 treated as 045     218 treated as 043     249 treated as 250
194 treated as 045     219 treated as 221     251 treated as 118
195 treated as 043     220 treated as 095     252 treated as 110
196 treated as 045     222 treated as 221     254 treated as 221
197 treated as 043     223 treated as 095
198 treated as 221     224 treated as 097

ตัวอักษรใด ๆ > 0 ไม่ได้อยู่ในรายการข้างต้นจะถือว่าเป็นตัวเองรวมทั้ง<CR>และ LF>< วิธีที่ง่ายที่สุดในการรวมอักขระแปลก ๆ เช่น<CR>และ<LF>เพื่อให้พวกเขาเป็นตัวแปรสภาพแวดล้อมและใช้การขยายตัวล่าช้าภายในอาร์กิวเมนต์บรรทัดคำสั่ง

ข้อ จำกัด อักขระสำหรับสตริงที่พบในไฟล์ที่ระบุโดยตัวเลือก / G: FILE และ / F: FILE
อักขระ nul (0x00) สามารถปรากฏในไฟล์ได้ แต่จะทำหน้าที่คล้ายกับสตริงสตริง C อักขระใด ๆ ที่อยู่หลังอักขระ nul จะถือว่าเป็นสตริงที่แตกต่างราวกับว่าอยู่ในบรรทัดอื่น

<CR>และ<LF>ตัวอักษรจะถือว่าเป็นจุดสิ้นสุดบรรทัดที่ยุติสตริงและจะไม่รวมอยู่ในสตริง

อักขระไบต์เดียวอื่น ๆ ทั้งหมดรวมอยู่ในสตริงอย่างสมบูรณ์

การค้นหาไฟล์ Unicode
FINDSTR ไม่สามารถค้นหา Unicode ส่วนใหญ่ (UTF-16, UTF-16LE, UTF-16BE, UTF-32) ได้อย่างถูกต้องเพราะมันไม่สามารถค้นหา nul bytes และ Unicode มักมีจำนวนไบต์ nul จำนวนมาก

อย่างไรก็ตามคำสั่ง TYPE แปลง UTF-16LE ด้วย BOM เป็นชุดอักขระไบต์เดียวดังนั้นคำสั่งเช่นนี้จะทำงานกับ UTF-16LE ด้วย BOM

type unicode.txt|findstr "search"

โปรดทราบว่าจุดโค้ด Unicode ที่ไม่ได้รับการสนับสนุนจากหน้ารหัสที่ใช้งานของคุณจะถูกแปลงเป็น?อักขระ

สามารถค้นหา UTF-8 ได้ตราบใดที่สตริงการค้นหาของคุณมีเพียง ASCII อย่างไรก็ตามเอาต์พุตคอนโซลของอักขระหลายไบต์ UTF-8 ใด ๆ จะไม่ถูกต้อง แต่ถ้าคุณเปลี่ยนเส้นทางไปยังไฟล์ผลลัพธ์จะถูกเข้ารหัส UTF-8 อย่างถูกต้อง โปรดทราบว่าหากไฟล์ UTF-8 มี BOM ดังนั้น BOM จะถือเป็นส่วนหนึ่งของบรรทัดแรกซึ่งอาจทำให้การค้นหาที่ตรงกับจุดเริ่มต้นของบรรทัดตรงข้าม

เป็นไปได้ที่จะค้นหาอักขระหลายไบต์ UTF-8 หากคุณใส่สตริงการค้นหาในไฟล์ค้นหาที่เข้ารหัส UTF-8 (โดยไม่มี BOM) และใช้ตัวเลือก / G

จุดสิ้นสุดของบรรทัด
FINDSTR แบ่งบรรทัดทันทีทุก ๆ <LF> การมีหรือไม่มี <CR> จะไม่มีผลกระทบต่อการขึ้นบรรทัดใหม่

การค้นหาข้ามตัวแบ่งบรรทัด
ตามที่คาดไว้ตัว.บ่งชี้ regex จะไม่ตรงกัน <CR> หรือ <LF> แต่เป็นไปได้ที่จะค้นหาข้ามตัวแบ่งบรรทัดโดยใช้สตริงการค้นหาบรรทัดคำสั่ง ทั้งอักขระ <CR> และ <LF> ต้องตรงกันอย่างชัดเจน หากพบการจับคู่หลายคู่สายจะมีการพิมพ์เฉพาะบรรทัดแรกของการจับคู่ FINDSTR จากนั้นกลับไปที่บรรทัดที่ 2 ในแหล่งที่มาและเริ่มการค้นหาอีกครั้ง - เรียงลำดับของคุณลักษณะประเภท "มองไปข้างหน้า"

สมมติว่า TEXT.TXT มีเนื้อหาเหล่านี้ (อาจเป็นรูปแบบ Unix หรือ Windows)

A
A
A
B
A
A

จากนั้นสคริปต์นี้

@echo off
setlocal
::Define LF variable containing a linefeed (0x0A)
set LF=^


::Above 2 blank lines are critical - do not remove

::Define CR variable containing a carriage return (0x0D)
for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

setlocal enableDelayedExpansion
::regex "!CR!*!LF!" will match both Unix and Windows style End-Of-Line
findstr /n /r /c:"A!CR!*!LF!A" TEST.TXT

ให้ผลลัพธ์เหล่านี้

1:A
2:A
5:A

การค้นหาตัวแบ่งบรรทัดโดยใช้ตัวเลือก / G: FILE นั้นไม่ถูกต้องเนื่องจากวิธีเดียวที่จะจับคู่ <CR> หรือ <LF> คือผ่านนิพจน์ช่วงคลาสอักขระ regex ที่คั่นอักขระ EOL

  • [<TAB>-<0x0B>] จับคู่ <LF> แต่ตรงกับ <TAB> และ <0x0B>

  • [<0x0C>-!] จับคู่ <CR> แต่ก็ตรงกับ <0x0C> และ!

    หมายเหตุ - ด้านบนเป็นการแสดงสัญลักษณ์ของกระแสข้อมูล regex เนื่องจากฉันไม่สามารถแสดงอักขระได้

ตอบคำถามต่อในตอนที่ 2 ด้านล่าง ...


46
ความสมบูรณ์ที่โดดเด่น ถ้าเพียงคำตอบทั้งหมดบนอินเทอร์เน็ตก็เป็นเช่นนี้
Mike Viens

1
เราพบปัญหากับaddpath.batจากQ141344และ findstr ซึ่งอาจเกี่ยวข้องกับปัญหาการแฮง Win7 ที่กล่าวถึงข้างต้น ฉันได้สร้างห้องแชทเพื่อลองและติดตามสิ่งนี้สำหรับผู้ที่สนใจ: chat.stackoverflow.com/rooms/13177/ …
matt wilkie

2
EDIT - อธิบายการแสดงตัวควบคุมเป็นจุดบน XP เอกสาร bugged /Sและ/Dตัวเลือกที่เกิดจากชื่อไฟล์สั้น ๆ 8.3
dbenham

1
แก้ไข - 1) ชื่อไฟล์ภายในไฟล์ที่ระบุโดย / F: FILE ต้องไม่ยกมา 2) การแปลงอักขระ ASCII ที่ขยายเพิ่มมีผลกับทั้งสตริงการค้นหาและชื่อไฟล์เมื่อระบุในบรรทัดคำสั่ง
dbenham

1
แก้ไข - เพิ่มข้อผิดพลาดที่บรรทัดสุดท้ายของอินพุต<LF>
piped

64

คำตอบดำเนินการต่อจากตอนที่ 1 ด้านบน - ฉันใช้จำนวนตัวอักษรสูงสุด 30,000 คำตอบแล้ว :-(

การสนับสนุนนิพจน์ทั่วไปที่ จำกัด (regex) การสนับสนุน
FINDSTR สำหรับนิพจน์ทั่วไปนั้นมี จำกัด มาก หากไม่ได้อยู่ในเอกสารวิธีใช้จะไม่ได้รับการสนับสนุน

นอกเหนือจากนั้นนิพจน์ regex ที่ได้รับการสนับสนุนจะถูกนำไปใช้งานในลักษณะที่ไม่ได้มาตรฐานอย่างสมบูรณ์ดังนั้นผลลัพธ์อาจแตกต่างกันซึ่งคาดว่ามาจากสิ่งที่ต้องการ grep หรือ perl

จุดยึดตำแหน่ง Regex Line ^ และ $
^ตรงกับจุดเริ่มต้นของอินพุตสตรีมรวมถึงตำแหน่งใด ๆ ที่ตามหลัง <LF> เนื่องจาก FINDSTR แบ่งบรรทัดหลัง <LF> regex ง่าย ๆ ของ "^" จะจับคู่ทุกบรรทัดภายในไฟล์เสมอแม้แต่ไฟล์ไบนารี

$ตรงกับตำแหน่งใด ๆ ก่อนหน้า <CR> ซึ่งหมายความว่าสตริงการค้นหา regex ที่มี$จะไม่ตรงกับบรรทัดใด ๆ ภายในไฟล์ข้อความสไตล์ Unix และจะไม่ตรงกับบรรทัดสุดท้ายของไฟล์ข้อความ Windows หากไม่มีเครื่องหมาย EOL ของ <CR> <LF>

หมายเหตุ - ตามที่กล่าวไว้ก่อนหน้านี้อินพุตและการเปลี่ยนเส้นทางไปยัง FINDSTR อาจ<CR><LF>ต่อท้ายที่ไม่ได้อยู่ในแหล่งที่มา เห็นได้ชัดว่าผลกระทบนี้สามารถค้นหา regex $ใช้ว่า

สตริงการค้นหาใด ๆ ที่มีอักขระก่อน^หรือหลัง$จะล้มเหลวในการค้นหาคู่ที่ตรงกันเสมอ

ตัวเลือกตำแหน่ง / B / E / X
ตัวเลือกตำแหน่งทำงานเช่นเดียวกับ^และ$ยกเว้นพวกเขายังทำงานสำหรับสตริงการค้นหาที่แท้จริง

/ B ฟังก์ชั่นเช่นเดียวกับ^ที่จุดเริ่มต้นของสตริงการค้นหา regex

/ E ทำหน้าที่เหมือนกับ$ในตอนท้ายของสตริงการค้นหา regex

/ X ฟังก์ชั่นเช่นเดียวกับการมีทั้ง^ที่จุดเริ่มต้นและ$ตอนท้ายของสตริงการค้นหา regex

ขอบเขตของคำ Regex
\<จะต้องเป็นคำแรกใน regex regex จะไม่ตรงกับสิ่งใดถ้าตัวละครอื่นนำหน้า \<สอดคล้องกับจุดเริ่มต้นอย่างมากของอินพุตจุดเริ่มต้นของบรรทัด (ตำแหน่งที่ตามหลัง <LF>) หรือตำแหน่งที่ตามตัวอักษร "ไม่ใช่คำ" ใด ๆ ทันที อักขระถัดไปไม่จำเป็นต้องเป็นอักขระ "คำ"

\>จะต้องเป็นคำสุดท้ายใน regex regex จะไม่ตรงกับสิ่งใดหากตัวละครอื่นติดตาม\>สอดคล้องกับทั้งจุดสิ้นสุดของการป้อนข้อมูลตำแหน่งก่อนหน้า <CR> หรือตำแหน่งที่อยู่หน้าอักขระ "ไม่ใช่คำ" ทันที อักขระก่อนหน้าไม่จำเป็นต้องเป็นอักขระ "คำ"

นี่คือรายการที่สมบูรณ์ของอักขระ "ไม่ใช่คำ" ซึ่งแสดงเป็นรหัสไบต์ทศนิยม หมายเหตุ - รายการนี้ถูกรวบรวมในเครื่องของสหรัฐอเมริกา ฉันไม่ทราบว่าอาจมีผลกระทบต่อภาษาอื่นในรายการนี้

001   028   063   179   204   230
002   029   064   180   205   231
003   030   091   181   206   232
004   031   092   182   207   233
005   032   093   183   208   234
006   033   094   184   209   235
007   034   096   185   210   236
008   035   123   186   211   237
009   036   124   187   212   238
011   037   125   188   213   239
012   038   126   189   214   240
014   039   127   190   215   241
015   040   155   191   216   242
016   041   156   192   217   243
017   042   157   193   218   244
018   043   158   194   219   245
019   044   168   195   220   246
020   045   169   196   221   247
021   046   170   197   222   248
022   047   173   198   223   249
023   058   174   199   224   250
024   059   175   200   226   251
025   060   176   201   227   254
026   061   177   202   228   255
027   062   178   203   229

ช่วงคลาสอักขระ Regex [xy]
ช่วงคลาสอักขระไม่ทำงานอย่างที่คาดไว้ ดูคำถามนี้: ทำไม findstr ไม่จัดการเคสอย่างถูกต้อง (ในบางสถานการณ์)? พร้อมกับคำตอบนี้: https://stackoverflow.com/a/8767815/1012053

ปัญหาคือ FINDSTR ไม่เรียงอักขระด้วยค่ารหัสไบต์ (โดยทั่วไปคิดว่าเป็นรหัส ASCII แต่ ASCII ถูกกำหนดจาก 0x00 - 0x7F เท่านั้น) การใช้งาน regex ส่วนใหญ่จะถือว่า [AZ] เป็นอักษรตัวพิมพ์ใหญ่ภาษาอังกฤษทั้งหมด แต่ FINDSTR ใช้ลำดับการเรียงที่สอดคล้องกันอย่างคร่าวๆกับการทำงานของ SORT ดังนั้น [AZ] รวมถึงตัวอักษรภาษาอังกฤษที่สมบูรณ์ทั้งตัวพิมพ์ใหญ่และตัวพิมพ์เล็ก (ยกเว้น "a") รวมถึงตัวอักษรอัลฟ่าที่ไม่ใช่ภาษาอังกฤษที่มีเครื่องหมายกำกับเสียง

ด้านล่างเป็นรายการที่สมบูรณ์ของตัวละครทั้งหมดที่ได้รับการสนับสนุนโดย FINDSTR เรียงลำดับตามลำดับการเรียงที่ใช้โดย FINDSTR เพื่อสร้างช่วงคลาสอักขระของ regex อักขระจะแสดงเป็นค่ารหัสไบต์ทศนิยม ฉันเชื่อว่าลำดับการเรียงจะเหมาะสมที่สุดหากดูตัวอักษรโดยใช้รหัสหน้า 437 หมายเหตุ - รายการนี้รวบรวมไว้ในเครื่องของสหรัฐอเมริกา ฉันไม่ทราบว่าอาจมีผลกระทบต่อภาษาอื่นในรายการนี้

001
002
003
004
005
006
007
008
014
015
016
017
018           
019
020
021
022
023
024
025
026
027
028
029
030
031
127
039
045
032
255
009
010
011
012
013
033
034
035
036
037
038
040
041
042
044
046
047
058
059
063
064
091
092
093
094
095
096
123
124
125
126
173
168
155
156
157
158
043
249
060
061
062
241
174
175
246
251
239
247
240
243
242
169
244
245
254
196
205
179
186
218
213
214
201
191
184
183
187
192
212
211
200
217
190
189
188
195
198
199
204
180
181
182
185
194
209
210
203
193
207
208
202
197
216
215
206
223
220
221
222
219
176
177
178
170
248
230
250
048
172
171
049
050
253
051
052
053
054
055
056
057
236
097
065
166
160
133
131
132
142
134
143
145
146
098
066
099
067
135
128
100
068
101
069
130
144
138
136
137
102
070
159
103
071
104
072
105
073
161
141
140
139
106
074
107
075
108
076
109
077
110
252
078
164
165
111
079
167
162
149
147
148
153
112
080
113
081
114
082
115
083
225
116
084
117
085
163
151
150
129
154
118
086
119
087
120
088
121
089
152
122
090
224
226
235
238
233
227
229
228
231
237
232
234

คำจำกัดความของคลาสอักขระ Regex และ BUG
ไม่เพียง แต่ FINDSTR จะจำกัดความยาวของคลาสอักขระสูงสุด 15 คำภายใน regex มันล้มเหลวในการจัดการกับความพยายามเกินขีด จำกัด อย่างถูกต้อง การใช้คำศัพท์คลาสอักขระ 16 ตัวขึ้นไปส่งผลให้ป๊อปอัพ Windows โต้ตอบระบุว่า"Find String (QGREP) Utility พบปัญหาและจำเป็นต้องปิดเราต้องขออภัยในความไม่สะดวก" ข้อความจะแตกต่างกันเล็กน้อยขึ้นอยู่กับรุ่นของ Windows นี่คือตัวอย่างหนึ่งของ FINDSTR ที่จะล้มเหลว:

echo 01234567890123456|findstr [0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]

ข้อผิดพลาดนี้ถูกรายงานโดยผู้ใช้ Judago DosTips ที่นี่ ได้รับการยืนยันใน XP, Vista และ Windows 7

การค้นหา Regex ล้มเหลว (และอาจหยุดโดยไม่มีกำหนด) หากมีรหัสไบต์ 0xFF (ทศนิยม 255) การ
ค้นหา regex ใด ๆ ที่มีรหัสไบต์ 0xFF (ทศนิยม 255) จะล้มเหลว มันล้มเหลวถ้ารหัสไบต์ 0xFF รวมโดยตรงหรือถ้ามันรวมอยู่ภายในช่วงชั้นตัวละครโดยปริยาย โปรดจำไว้ว่าช่วงคลาสของอักขระ FINDSTR จะไม่เรียงอักขระตามค่ารหัสไบต์ อักขระ<0xFF>ปรากฏค่อนข้างเร็วในลำดับการเรียงระหว่าง<space>และ<tab>อักขระ ดังนั้นคลาสคลาสตัวละครใด ๆ ที่รวมทั้ง<space>และ<tab>จะล้มเหลว

พฤติกรรมที่แน่นอนเปลี่ยนไปเล็กน้อยขึ้นอยู่กับรุ่นของ Windows Windows 7 จะหยุดทำงานหากไม่มีการรวม 0xFF ไว้ XP ไม่แฮงค์ แต่ล้มเหลวในการค้นหาคู่ที่ตรงกันและพิมพ์ข้อความแสดงข้อผิดพลาดต่อไปนี้ - "กระบวนการพยายามเขียนลงในไพพ์ที่ไม่มีอยู่"

ฉันไม่สามารถเข้าถึงเครื่อง Vista ได้อีกต่อไปดังนั้นฉันจึงไม่สามารถทดสอบกับ Vista ได้

Regex bug: .และ[^anySet]สามารถจับคู่ End-Of-File ได้
regex .meta-เพียงตัวละครควรจะตรงกับตัวละครอื่น ๆ กว่าหรือ<CR> <LF>มีข้อผิดพลาดที่ช่วยให้มันตรงกับปลายของไฟล์ถ้าบรรทัดสุดท้ายในไฟล์ไม่ได้ยกเลิกโดยเป็นหรือ<CR> <LF>อย่างไรก็ตามไฟล์.จะไม่ตรงกับไฟล์ว่าง

ตัวอย่างเช่นไฟล์ชื่อ "test.txt" ที่มีบรรทัดเดียวxโดยไม่ยกเลิก<CR>หรือ<LF>จะตรงกับสิ่งต่อไปนี้:

findstr /r x......... test.txt

ข้อผิดพลาดนี้ได้รับการยืนยันใน XP และ Win7

ดูเหมือนจะเป็นจริงสำหรับชุดอักขระเชิงลบ สิ่งที่ชอบ[^abc]จะตรงกับจุดสิ้นสุดของไฟล์ ชุดอักขระเชิงบวกเช่น[abc]ดูเหมือนว่าจะทำงานได้ดี ฉันเพิ่งทดสอบสิ่งนี้บน Win7


1
findstr ยังเป็นรถจัดการกับไฟล์ขนาดใหญ่ ไฟล์> 2GB อาจทำให้ findstr หยุดทำงาน มันไม่ได้เกิดขึ้นเสมอไป ในการยืนยันข้อบกพร่องฉันค้นหาไฟล์ที่เป็น 2.3GB ซึ่งไม่ได้แขวน แฮงค์แม้ว่าจะค้นหาไฟล์เดียวเท่านั้น วิธีแก้ปัญหาคือการท่อส่งออกของเข้าtype findstr
ไม่แยแส

อาจเป็นเรื่องที่คุ้มค่าที่จะกล่าวถึงอย่างชัดเจนว่าfindstrรองรับ/c:สตริงการค้นหาหลายรายการ ฉันรู้ว่าคำตอบของคุณแสดงให้เห็นถึงสิ่งนี้ แต่มันเป็นสิ่งที่ไม่ได้จัดทำเป็นเอกสาร และฉันค่อนข้างประหลาดใจที่ได้เรียนรู้คุณสมบัติหลังจากใช้งานไปfindstrโดยไม่ใช้งานมาสองสามปี
ไม่แยแส

@CraigYoung - คุณถูกต้องเกี่ยวกับแหล่งที่มาของสตริงการค้นหา ฉันแก้ไขคำตอบของฉันขอบคุณ
dbenham

1
ในการตรวจสอบเพิ่มเติมดูเหมือนว่าจะมีการเปลี่ยนแปลงในLFปัญหาที่คุณบันทึกไว้ ฉันรู้ว่าไฟล์ทดสอบของฉันไม่ได้สิ้นสุดLFเพราะฉันใช้copyในโหมดผนวกเพื่อสร้าง ฉันใส่เซสชั่นบรรทัดคำสั่งเพื่อแสดงปัญหาในคำตอบ ( stackoverflow.com/a/22943056/224704 ) โปรดทราบว่าอินพุตไม่ได้ถูกเปลี่ยนเส้นทาง แต่การค้นหาหยุดทำงาน คำสั่งค้นหาเดียวกันแน่นอนไม่แขวนLFกับไฟล์ขนาดเล็กที่เหมือนกันไม่ได้จบลงด้วย
ไม่แยแส

1
การค้นพบใหม่ (Win7): findstr /R /C:"^[0-9][0-9]* [0-3][0-9][0-9]-[0-9][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9]* [0-9]*\.[0-9]*"(15 ตัวอักษรคลาส) - ErrorLevel = -1073740791 (0xC0000409), หน้าต่างข้อผิดพลาดโต้ตอบ : Find String (QGREP) Utility has stopped working; หลังจากลบเมตาอักขระหนึ่งคลาสหรือสองตัว ( *\.) มันใช้งานได้ ...
aschipfl

7

findstr บางครั้งแฮงค์โดยไม่คาดคิดเมื่อค้นหาไฟล์ขนาดใหญ่

ฉันไม่ได้ยืนยันเงื่อนไขหรือขนาดที่แน่นอน ฉันสงสัยว่าไฟล์ใด ๆ ที่มีขนาดใหญ่กว่า 2GB อาจมีความเสี่ยง

ฉันมีประสบการณ์ที่หลากหลายกับสิ่งนี้ดังนั้นมันจึงเป็นมากกว่าแค่ขนาดไฟล์ ดูเหมือนว่าอาจเป็นรูปแบบของFINDSTR ที่แฮงค์บน XP และ Windows 7 หากอินพุตที่เปลี่ยนเส้นทางไม่ได้จบด้วย LFแต่ดังที่แสดงให้เห็นถึงปัญหานี้โดยเฉพาะเมื่อไม่มีการเปลี่ยนเส้นทางอินพุต

เซสชันบรรทัดคำสั่งต่อไปนี้ (Windows 7) สาธิตวิธีfindstrแขวนเมื่อค้นหาไฟล์ 3GB

C:\Data\Temp\2014-04>echo 1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890> T100B.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,10) do @type T100B.txt >> T1KB.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1KB.txt >> T1MB.txt

C:\Data\Temp\2014-04>for /L %i in (1,1,1000) do @type T1MB.txt >> T1GB.txt

C:\Data\Temp\2014-04>echo find this line>> T1GB.txt

C:\Data\Temp\2014-04>copy T1GB.txt + T1GB.txt + T1GB.txt T3GB.txt
T1GB.txt
T1GB.txt
T1GB.txt
        1 file(s) copied.

C:\Data\Temp\2014-04>dir
 Volume in drive C has no label.
 Volume Serial Number is D2B2-FFDF

 Directory of C:\Data\Temp\2014-04

2014/04/08  04:28 PM    <DIR>          .
2014/04/08  04:28 PM    <DIR>          ..
2014/04/08  04:22 PM               102 T100B.txt
2014/04/08  04:28 PM     1 020 000 016 T1GB.txt
2014/04/08  04:23 PM             1 020 T1KB.txt
2014/04/08  04:23 PM         1 020 000 T1MB.txt
2014/04/08  04:29 PM     3 060 000 049 T3GB.txt
               5 File(s)  4 081 021 187 bytes
               2 Dir(s)  51 881 050 112 bytes free
C:\Data\Temp\2014-04>rem Findstr on the 1GB file does not hang

C:\Data\Temp\2014-04>findstr "this" T1GB.txt
find this line

C:\Data\Temp\2014-04>rem On the 3GB file, findstr hangs and must be aborted... even though it clearly reaches end of file

C:\Data\Temp\2014-04>findstr "this" T3GB.txt
find this line
find this line
find this line
^C
C:\Data\Temp\2014-04>

หมายเหตุผมได้รับการตรวจสอบในตัวแก้ไข hex CRLFว่าสายทั้งหมดจะสิ้นสุดลงด้วย ความผิดปกติเพียงอย่างเดียวคือไฟล์ถูกยกเลิกด้วย0x1Aเนื่องจากวิธีการcopyทำงานการทำงานหมายเหตุ แต่ที่ผิดปกตินี้ไม่ก่อให้เกิดปัญหากับไฟล์ "เล็ก" a

ด้วยการทดสอบเพิ่มเติมฉันได้ยืนยันสิ่งต่อไปนี้:

  • ใช้copyกับ/bตัวเลือกสำหรับการป้องกันไม่ให้แฟ้มไบนารีนอกจากของ0x1Aตัวอักษรและfindstrไม่แขวนบนไฟล์ 3GB
  • การยกเลิกไฟล์ 3GB ด้วยตัวอักษรที่แตกต่างกันยังทำให้ a findstrค้าง
  • 0x1Aตัวละครที่ไม่ก่อให้เกิดปัญหาใด ๆ ในไฟล์ "เล็ก" (ในทำนองเดียวกันสำหรับอักขระที่สิ้นสุดอื่น ๆ )
  • การเพิ่มCRLFหลังจาก0x1Aแก้ไขปัญหาแล้ว (LFโดยตัวมันเองอาจจะพอเพียง)
  • ใช้typeเพื่อไพพ์ไฟล์ลงในfindstrงานโดยไม่หยุดทำงาน (นี่อาจเป็นเพราะผลข้างเคียงของอย่างใดอย่างหนึ่งtypeหรือ|ที่แทรกสิ้นเพิ่มเติมของสาย.)
  • การใช้อินพุตที่เปลี่ยนเส้นทาง<ยังทำให้findstrแฮงค์ แต่คาดว่าจะเป็นเช่นนี้ ตามที่อธิบายไว้ในโพสต์ของ dbenham : "การป้อนข้อมูลที่ถูกเปลี่ยนเส้นทางต้องลงท้ายด้วยLF "

1
+1 ฉันสามารถยืนยันปัญหาบนเครื่อง Win7 ของฉัน ไฟล์ตรง 2GiB <LF>ในขนาดแขวนเมื่อตัวละครที่ผ่านมาไม่ได้ ไฟล์ที่มีขนาดเล็กกว่าสองไบต์ไม่ได้แขวน น่ารังเกียจมาก!
dbenham

6

เมื่อมีหลายคำสั่งอยู่ในวงเล็บและมีการเปลี่ยนเส้นทางไฟล์ไปยังบล็อกทั้งหมด:

< input.txt (
   command1
   command2
   . . .
) > output.txt

... จากนั้นไฟล์จะยังคงเปิดอยู่ตราบเท่าที่คำสั่งในบล็อกนั้นแอ็คทีฟดังนั้นคำสั่งอาจย้ายตัวชี้ไฟล์ของไฟล์ที่ถูกเปลี่ยนเส้นทาง ทั้งคำสั่ง MORE และ FIND ย้ายตัวชี้ไฟล์ Stdin ไปที่จุดเริ่มต้นของไฟล์ก่อนที่จะประมวลผลดังนั้นไฟล์เดียวกันอาจถูกประมวลผลหลายครั้งภายในบล็อก ตัวอย่างเช่นรหัสนี้:

more < input.txt >  output.txt
more < input.txt >> output.txt

... ให้ผลลัพธ์ที่เหมือนกันมากกว่านี้:

< input.txt (
   more
   more
) > output.txt

รหัสนี้:

find    "search string" < input.txt > matchedLines.txt
find /V "search string" < input.txt > unmatchedLines.txt

... ให้ผลลัพธ์ที่เหมือนกันมากกว่านี้:

< input.txt (
   find    "search string" > matchedLines.txt
   find /V "search string" > unmatchedLines.txt
)

FINDSTR นั้นแตกต่างกัน มันไม่ย้ายตัวชี้ไฟล์ Stdin จากตำแหน่งปัจจุบัน ตัวอย่างเช่นรหัสนี้แทรกบรรทัดใหม่หลังบรรทัดค้นหา:

call :ProcessFile < input.txt
goto :EOF

:ProcessFile
   rem Read the next line from Stdin and copy it
   set /P line=
   echo %line%
   rem Test if it is the search line
   if "%line%" neq "search line" goto ProcessFile
rem Insert the new line at this point
echo New line
rem And copy the rest of lines
findstr "^"
exit /B

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

พฤติกรรมนี้ถูกรายงานครั้งแรกโดยjebที่โพสต์นี้


แก้ไข 2018-08-18 : รายงานข้อผิดพลาด FINDSTR ใหม่

คำสั่ง FINDSTR มีข้อผิดพลาดแปลก ๆ ที่เกิดขึ้นเมื่อคำสั่งนี้ใช้แสดงตัวอักษรสีและเอาท์พุทคำสั่งดังกล่าวจะถูกเปลี่ยนเส้นทางไปยังอุปกรณ์ CON สำหรับรายละเอียดเกี่ยวกับวิธีใช้คำสั่ง FINDSTR เพื่อแสดงข้อความเป็นสีให้ดูหัวข้อนี้

เมื่อเอาต์พุตของคำสั่ง FINDSTR รูปแบบนี้ถูกเปลี่ยนเส้นทางไปยัง CON สิ่งที่แปลกเกิดขึ้นหลังจากที่ข้อความถูกส่งออกในสีที่ต้องการ: ข้อความทั้งหมดหลังจากที่มันถูกส่งออกเป็นตัวอักษร "มองไม่เห็น" แม้ว่าคำอธิบายที่แม่นยำยิ่งขึ้นคือข้อความนั้น เอาต์พุตเป็นข้อความสีดำบนพื้นหลังสีดำ ข้อความต้นฉบับจะปรากฏขึ้นหากคุณใช้คำสั่ง COLOR เพื่อรีเซ็ตสีพื้นหน้าและสีพื้นหลังของทั้งหน้าจอ อย่างไรก็ตามเมื่อข้อความเป็น "ล่องหน" เราสามารถรันคำสั่ง SET / P ดังนั้นตัวละครทุกตัวที่ป้อนจะไม่ปรากฏบนหน้าจอ พฤติกรรมนี้อาจถูกใช้เพื่อป้อนรหัสผ่าน

@echo off
setlocal

set /P "=_" < NUL > "Enter password"
findstr /A:1E /V "^$" "Enter password" NUL > CON
del "Enter password"
set /P "password="
cls
color 07
echo The password read is: "%password%"

2

ฉันต้องการรายงานข้อผิดพลาดเกี่ยวกับส่วนแหล่งข้อมูลเพื่อค้นหาในคำตอบแรกเมื่อใช้en dash (-) หรือem dash (-) ภายในชื่อไฟล์

โดยเฉพาะอย่างยิ่งหากคุณกำลังจะใช้ตัวเลือกแรก - ชื่อไฟล์ที่ระบุเป็นอาร์กิวเมนต์ไฟล์จะไม่ถูกพบ ทันทีที่คุณใช้ตัวเลือก 2 - stdin ผ่านการเปลี่ยนเส้นทางหรือ 3 - data stream จากไปป์ findstr จะค้นหาไฟล์

ตัวอย่างเช่นสคริปต์แบทช์ง่าย ๆ นี้:

echo off
chcp 1250 > nul
set INTEXTFILE1=filename with – dash.txt
set INTEXTFILE2=filename with — dash.txt

rem 3 way of findstr use with en dashed filename
echo.
echo Filename with en dash:
echo.
echo 1. As argument
findstr . "%INTEXTFILE1%"
echo.
echo 2. As stdin via redirection
findstr . < "%INTEXTFILE1%"
echo.
echo 3. As datastream from a pipe
type "%INTEXTFILE1%" | findstr .
echo.
echo.
rem The same set of operations with em dashed filename
echo Filename with em dash:
echo.
echo 1. As argument
findstr . "%INTEXTFILE2%"
echo.
echo 2. As stdin via redirection
findstr . < "%INTEXTFILE2%"
echo.
echo 3. As datastream from a pipe
type "%INTEXTFILE2%" | findstr .
echo.

pause

จะพิมพ์:

ชื่อไฟล์พร้อม en dash:

  1. เป็นอาร์กิวเมนต์
    FINDSTR: ไม่สามารถเปิดชื่อไฟล์ด้วย - dash.txt

  2. ในฐานะ stdin ผ่านการเปลี่ยนเส้นทาง
    ฉันเป็นไฟล์ที่มี en dash

  3. ในฐานะ datastream จากไปป์
    ฉันเป็นไฟล์ที่มี en dash

ชื่อไฟล์ที่มีเส้นประ em:

  1. เป็นอาร์กิวเมนต์
    FINDSTR: ไม่สามารถเปิดชื่อไฟล์ด้วย - dash.txt

  2. ในฐานะ stdin ผ่านการเปลี่ยนเส้นทาง
    ฉันเป็นไฟล์ที่มี em dash

  3. ในฐานะ datastream จากไปป์
    ฉันเป็นไฟล์ที่มี em dash

หวังว่ามันจะช่วย

เอ็ม


1
สวัสดี matro ในขณะที่ความคิดเห็นของคุณอาจถูกต้องฉันไม่แน่ใจว่าพวกเขาไม่ได้ตอบคำถามจริง
Wai Ha Lee

ฉันเชื่อว่านี่เป็นปัญหายูนิโค้ดซึ่ง FINDSTR ไม่สนับสนุน การเปลี่ยนเส้นทาง CMD.EXE สามารถเปิดชื่อไฟล์อย่างถูกต้องด้วย unicode ได้เช่นเดียวกับคำสั่ง TYPE แต่ที่ใดที่หนึ่งตามบรรทัด FINDSTR จะแปลงทั้งเส้นประและเส้นประเป็นเส้นประปกติและแน่นอนว่าระบบปฏิบัติการไม่สามารถหาชื่อนั้นได้ หากคุณสร้างไฟล์อื่นเพื่อแทนที่เส้นประสำหรับ en-dash และ / หรือ em-dash แล้ว FINDSTR จะค้นหาไฟล์ dash หากระบุชื่อที่มี en-dash หรือ em-dash
dbenham

ฉันจะจัดประเภทของปัญหานี้เป็นข้อ จำกัด มากกว่าข้อบกพร่อง
dbenham

ที่จริงแล้วนี่ไม่ใช่ปัญหายูนิโค้ดมากนักเพราะมันมีการขยาย ASCII ฉันได้รับการบันทึกปัญหานี้ในคำตอบเดิมของฉันภายใต้หัวข้อจำนวนอักขระสูงสุดสำหรับพารามิเตอร์บรรทัดคำสั่ง - การแปลง FINDSTR แปลงรหัส ASCII เพิ่มเติมจำนวนหนึ่งเป็น ASCII จริง "ที่เกี่ยวข้อง" รวมถึง en-dash และ em-dash
dbenham

1

findstrคำสั่งกำหนดErrorLevel(หรือรหัสออก)ให้เป็นหนึ่งในค่าต่อไปนี้ที่ระบุว่าไม่มีสวิทช์ไม่ถูกต้องหรือเข้ากันไม่ได้และไม่มีสตริงการค้นหาเกินขีด จำกัด ระยะเวลาบังคับ:

  • 0 เมื่อพบอย่างน้อยหนึ่งคู่ในหนึ่งบรรทัดตลอดทั้งไฟล์ที่ระบุ
  • 1 มิฉะนั้น;

สายถือว่ามีการแข่งขันเมื่อ:

  • ไม่มี/Vตัวเลือกใด ๆและการแสดงออกของการค้นหาเกิดขึ้นอย่างน้อยหนึ่งครั้ง
  • /Vตัวเลือกที่จะได้รับและการแสดงออกการค้นหาไม่เกิดขึ้น;

ซึ่งหมายความว่า/Vตัวเลือกนี้จะเปลี่ยนการคืนค่าErrorLevelด้วย แต่มันไม่เพียงแค่เปลี่ยนกลับ!

ตัวอย่างเช่นเมื่อคุณมีไฟล์test.txtที่มีสองบรรทัดซึ่งหนึ่งในนั้นมีสตริงtextแต่คนอื่น ๆ ไม่ได้ทั้งสองfindstr "text" "test.txt"และfindstr /V "text" "test.txt"กลับของErrorLevel0

โดยทั่วไปคุณสามารถกล่าวว่าหากfindstrผลตอบแทนอย่างน้อยบรรทัดErrorLevelถูกตั้งไว้ที่อื่นเพื่อ01

โปรดทราบว่า/Mตัวเลือกไม่ส่งผลกระทบต่อErrorLevelค่าเพียงแค่เปลี่ยนผลลัพธ์

(เพียงเพื่อความครบถ้วนสมบูรณ์ที่ว่าfindคำสั่งจะทำงานตรงเช่นเดียวกับความเคารพใน/VตัวเลือกErrorLevelนั้น/Cตัวเลือกที่ไม่ส่งผลกระทบErrorLevel.)


1

findstr มีข้อผิดพลาดสีที่ผมอธิบายและการแก้ไขที่/superuser/1535810/is-there-a-better-way-to-mitigate-this-obscure-color-bug-when-piping-to -findstr / 1538802? noredirect = 1 # comment2339443_1538802

เพื่อสรุปเธรดนั้นข้อผิดพลาดคือถ้าอินพุตถูกไพพ์ไปยัง FINDSTR ภายในบล็อกของโค้ดที่อยู่ในวงเล็บ, colorline รหัสยกเว้น ANSI แบบอินไลน์หยุดทำงานในคำสั่งที่ดำเนินการในภายหลัง ตัวอย่างของรหัสแบบอินไลน์คือ: echo %magenta%Alert: Something bad happened%yellow%(โดยที่สีม่วงแดงและสีเหลืองเป็น vars ที่กำหนดไว้ก่อนหน้านี้ในไฟล์. bat เป็น colorcodes ของ ANSI ที่สอดคล้องกัน)

ทางออกแรกของฉันคือเรียกรูทีนย่อย do-nothing หลังจาก FINDSTR อย่างใดการโทรหรือกลับ "รีเซ็ต" สิ่งที่จะต้องมีการรีเซ็ต

ต่อมาฉันค้นพบวิธีแก้ไขปัญหาอื่นที่น่าจะมีประสิทธิภาพมากกว่า: วางวลี FINDSTR ไว้ในวงเล็บดังตัวอย่างต่อไปนี้: echo success | ( FINDSTR /R success ) การวางวลี FINDSTR ภายในบล็อกที่ซ้อนกันของรหัสจะปรากฏขึ้นเพื่อแยกข้อผิดพลาด colorcode ของ FINDSTR บล็อก. บางทีเทคนิคนี้อาจแก้ปัญหาผลข้างเคียงอื่น ๆ ของ FINDSTR ด้วยเช่นกัน


หาที่ดี แต่กฎของคุณสามารถทำให้ง่ายขึ้น (อย่างน้อยในเครื่อง Windows 10 ของฉัน) FINDSTR ป้องกันลำดับการหลบหนีของคอนโซลทั้งหมดจากการทำงานสำหรับคำสั่งที่ตามมาภายในบล็อกคำสั่งเดียวกัน ไม่สำคัญว่า FINDSTR จะอ่านไปป์อินพุตที่เปลี่ยนเส้นทางหรือไฟล์ ความล้มเหลวในลำดับการหลบหนีไม่ได้ จำกัด อยู่ที่รหัสสี บล็อกคำสั่งคือชุดคำสั่งใด ๆ ที่อยู่ในวงเล็บและ / หรือคำสั่งที่ต่อกันผ่าน &, &&& หรือ | |
dbenham

@ dbenham: ปัญหาทั่วไปที่ดี คุณรู้หรือไม่ว่าโซลูชันของฉัน - การซ้อนวลี FINDSTR ไว้ในวงเล็บ - ทำงานในกรณีทั่วไปด้วยหรือไม่ และคุณรู้หรือไม่ว่าทางออกของฉันมีผลข้างเคียงที่ไม่พึงประสงค์หรือไม่?
Dolores Stevens

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

-1

/ D เคล็ดลับสำหรับหลายไดเรกทอรี: ใส่รายการไดเรกทอรีของคุณก่อนที่จะค้นหาสตริง สิ่งเหล่านี้ทำงานได้ทั้งหมด:

findstr /D:dir1;dir2 "searchString" *.*
findstr /D:"dir1;dir2" "searchString" *.*
findstr /D:"\path\dir1\;\path\dir2\" "searchString" *.*

\คาดว่าจะเป็นเส้นทางที่เป็นญาติไปยังสถานที่ถ้าคุณไม่ได้เริ่มต้นด้วยไดเรกทอรี การล้อมรอบพา ธ ด้วย"เป็นทางเลือกถ้าไม่มีช่องว่างในชื่อไดเร็กทอรี ตอนจบ\เป็นทางเลือก ผลลัพธ์ของตำแหน่งจะรวมถึงเส้นทางใดก็ตามที่คุณให้ "มันจะทำงานโดยมีหรือไม่มีรอบรายการไดเรกทอรีที่มี


ฉันไม่เห็นสิ่งใดที่ไม่มีเอกสารที่นี่ ตัวเลือก / D อธิบายไว้ในวิธีใช้ในตัว นี่ไม่ใช่คำถามสำหรับเคล็ดลับทั่วไปเกี่ยวกับวิธีใช้ FINDSTR มีวัตถุประสงค์อย่างเคร่งครัดเพื่อแสดงรายการคุณลักษณะข้อ จำกัด และ / หรือข้อบกพร่องที่ไม่มีเอกสาร
dbenham

1
@ dbenham จริงมันไม่ได้ลงทะเบียนจริง ๆ แต่ฉันพบว่าฉันต้อง dicker กับ findstr เพื่อให้ได้ผลลัพธ์ที่ฉันต้องการและฉันกำลังแบ่งปันสิ่งที่ฉันพบว่าทำงาน DID ดังนั้นคนจะไม่เสียเวลาทดลองกับคำสั่งที่ไม่ทำงาน hth (ฉันเสียใจที่คุณไม่ชอบข้อมูลของฉัน - มันเป็นเพียงความตั้งใจที่จะสร้างสรรค์)
gordon

IMHO สวิตช์ / D มีการอธิบายไว้อย่างชัดเจนในตัวช่วย: /D:dirlist Search a semicolon-delimited list of directoriesและวางไว้ก่อนสตริงการค้นหาดังนั้นฉันไม่เข้าใจว่า "คุณพบ" เกี่ยวกับสวิตช์ / D คืออะไร (และคำสั่ง "อะไรที่" ไม่ทำงาน ") ...
Aacini

@Aacini ในหลาย ๆ ภาษาลำดับของคุณสมบัติไม่สำคัญ ฉันเข้าใจเอกสารสำหรับfindstrรายการ / D ก่อน ใช่ฉันไม่มีข้อโต้แย้งเกี่ยวกับคุณสมบัติที่บันทึกไว้ แต่มันไม่ได้บันทึกเกี่ยวกับ gotcha ที่ลำดับของคุณลักษณะนั้นสำคัญ ฉันทำงาน commandline น้อยมากดังนั้นเมื่อฉันสั่งคำสั่ง cobbling ไม่ทราบว่าคำสั่งสร้างความแตกต่างฉันเพียงแค่เพิ่มคุณสมบัติตามที่ฉันได้รับพวกเขา (และตัวอักษร C precedes D) ฉันรู้สึกท้อแท้จริงๆและแบ่งปันประสบการณ์ "พบ" ของฉันให้กับคนอื่น ๆ ที่ไม่ค่อยได้ทำงานกับ commandline
gordon

1
ลำดับของแอตทริบิวต์ที่เป็นตัวเลือกมักจะไม่สำคัญ findstrเอกสารระบุว่าstringsเป็นส่วนหนึ่งที่ไม่จำเป็นและที่คุณต้องวางไว้หลังจากที่ตัวเลือกคุณลักษณะและก่อนที่จะมีตัวเลือกรายการชื่อไฟล์ หาก "สิ่งที่คุณพบ" คือการใช้คำสั่งโดยไม่ทำตามรูปแบบการใช้งานของมันทำให้เกิดข้อผิดพลาดจุดนั้นจะได้รับการบันทึกไว้อย่างดี ดูไวยากรณ์คำสั่ง : "ไวยากรณ์ปรากฏขึ้นตามลำดับที่คุณต้องพิมพ์คำสั่งและพารามิเตอร์ใด ๆ ที่ตามมา"
Aacini
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.