การเปลี่ยนเส้นทางเอาต์พุตจากภายในไฟล์ Batch


110

ฉันกำลังสร้างไฟล์แบตช์ด้วยคำสั่งง่ายๆเพื่อรวบรวมข้อมูลจากระบบ ไฟล์แบตช์มีคำสั่งเพื่อรับข้อมูลเวลาข้อมูล IP ผู้ใช้ ฯลฯ

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

โปรดทราบว่าฉันไม่ต้องการเรียกใช้ชุดงานจาก cmd จากนั้นเปลี่ยนเส้นทางเอาต์พุต ฉันต้องการเปลี่ยนเส้นทางเอาต์พุตจากภายในชุดงานหากเป็นไปได้

คำตอบ:


161

วิธีไร้เดียงสาง่ายๆที่ช้าเพราะเปิดและวางตำแหน่งตัวชี้ไฟล์ไปที่ End-Of-File หลายครั้ง

@echo off
command1 >output.txt
command2 >>output.txt
...
commandN >>output.txt

วิธีที่ดีกว่า - เขียนง่ายกว่าและเร็วกว่าเพราะเปิดไฟล์และวางตำแหน่งเพียงครั้งเดียว

@echo off
>output.txt (
  command1
  command2
  ...
  commandN
)

อีกวิธีที่ดีและรวดเร็วที่เปิดและวางตำแหน่งไฟล์เพียงครั้งเดียว

@echo off
call :sub >output.txt
exit /b

:sub
command1
command2
...
commandN

แก้ไข 2020-04-17

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

call :sub 9>File1.txt 8>File2.txt
exit /b

:sub
echo Screen message 1
>&9 File 1 message 1
>&8 File 2 message 1
echo Screen message 2
>&9 File 1 message 2
>&8 File 2 message 2
exit /b

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

3>File1.txt ( 4>File2.txt call :sub)
exit /b

:sub
etc.

2
ชอบวิธีแก้ปัญหาที่ฉันสามารถตั้งค่าสำหรับส่วนที่เหลือของไฟล์
แซม

3
โปรดทราบว่าโซลูชันการโทรจะเปลี่ยน% 0ของคุณ(เป็นย่อยในกรณีนี้) ซึ่งอาจเป็นหรือไม่ใช่สิ่งที่คุณต้องการ
Jannes

2
@ Jannes - จริง แต่คุณสามารถรับข้อมูลเกี่ยวกับสคริปต์แบตช์ที่กำลังทำงานอยู่ได้ตลอดเวลาหากคุณเพิ่มตัวปรับแต่ง ตัวอย่างเช่น%~f0ให้พา ธ แบบเต็มไปยังสคริปต์แบตช์เสมอแม้ว่าจะอยู่ในรูทีนย่อย CALLed: ก็ตาม
dbenham

3
@ThariqNugrohotomo ->output.txt 2>&1
dbenham

2
@Moondra - นั่นคือไวยากรณ์ชุดมาตรฐานสำหรับการเรียกรูทีนย่อยที่มีป้ายกำกับภายในสคริปต์เดียวกัน ดำเนินการcmd /?หรือhelp cmdจากบรรทัดคำสั่งคอนโซลสำหรับเอกสารประกอบ เคล็ดลับของวิธีที่สามคือการเปลี่ยนเส้นทางบน CALL ใช้กับคำสั่งทั้งหมดภายในรูทีนย่อย CALLed
dbenham

66

หากคุณต้องการให้สตรีมทั้งออกและผิดพลาดเปลี่ยนเส้นทาง

dir >> a.txt 2>&1

27
+1. นอกจากนี้ยังเป็นมูลค่าการชี้ให้เห็นว่าการใช้จะผนวกกับ>> a.txtการเขียนทับแทนการใช้งานa.txt stackoverflow.com/q/4458231/1098302>
Aaron

สวัสดีมีวิธีเปลี่ยนเส้นทางเอาต์พุตบนคอนโซลด้วยหรือไม่?
Sandeep Singh

นั่นคือสิ่งที่มันทำ
Kalpesh Soni

16

ฉันรู้ว่านี่เป็นโพสต์ที่เก่ากว่า แต่จะมีคนสะดุดในการค้นหาของ Google และดูเหมือนว่าคำถามบางอย่างที่ OP ถามในความคิดเห็นไม่ได้ระบุไว้เป็นพิเศษ นอกจากนี้โปรดพูดง่ายๆกับฉันเนื่องจากนี่เป็นคำตอบแรกของฉันที่โพสต์บน SO :)

ในการเปลี่ยนทิศทางเอาต์พุตไปยังไฟล์โดยใช้ชื่อไฟล์ที่สร้างขึ้นแบบไดนามิกวิธี go-to (read: quick & dirty) ของฉันเป็นโซลูชันที่สองที่นำเสนอโดย @dbenham ตัวอย่างเช่นสิ่งนี้:

@echo off
> filename_prefix-%DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log (
echo Your Name Here
echo Beginning Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
REM do some stuff here
echo Your Name Here
echo Ending Date/Time: %DATE:~-4%-%DATE:~4,2%-%DATE:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%.log
)

จะสร้างไฟล์เหมือนที่คุณเห็นในภาพหน้าจอของไฟล์ในไดเร็กทอรีเป้าหมาย

ที่จะมีผลลัพธ์นี้:

Your Name Here
Beginning Date/Time: 2016-09-16_141048.log
Your Name Here
Ending Date/Time: 2016-09-16_141048.log

นอกจากนี้โปรดทราบว่าโซลูชันนี้ขึ้นอยู่กับสถานที่ดังนั้นโปรดใช้ความระมัดระวังว่าจะใช้อย่างไร / เมื่อใด


ขอบคุณสิ่งนี้มีประโยชน์ คำถามด่วนมีเหตุผลว่าทำไมคุณถึงใช้. log vs .txt? นั่นสร้างความแตกต่างหรือไม่?
Moondra

1
@ Moondra ไม่มันไม่ได้ มันเป็นแค่ความหมายในกรณีนี้ ไม่ได้หมายความว่าไม่มีแอปพลิเคชันที่ต้องใช้ / grep ตามประเภทไฟล์ดังนั้นโปรดทราบว่าไฟล์ของคุณถูกใช้งานหรือไม่
Anthony

9
echo some output >"your logfile"

หรือ

(
 echo some output
 echo more output
)>"Your logfile"

ควรกรอกบิล

หากคุณต้องการAPPENDส่งออกให้ใช้>>แทน>. >จะเริ่มไฟล์บันทึกใหม่


9
@echo off
>output.txt (
echo Checking your system infor, Please wating...

systeminfo | findstr /c:"Host Name" 
systeminfo | findstr /c:"Domain"

ipconfig /all | find "Physical Address" 

ipconfig | find "IPv4" 
ipconfig | find "Default Gateway"

)

@pause

ฉันคิดว่านี่เป็นวิธีที่สง่างามที่สุด ขอบคุณเวสลีย์!
Kiswanij

5

มีโปรแกรมเล็ก ๆ ที่น่าสนใจที่คุณสามารถใช้เพื่อเปลี่ยนเส้นทางผลลัพธ์ไปยังไฟล์และคอนโซล

some_command  ^|  TEE.BAT  [ -a ]  filename 


4

เพิ่มสองบรรทัดนี้ใกล้ด้านบนของไฟล์แบตช์ของคุณ stdout และ stderr after ทั้งหมดจะถูกเปลี่ยนเส้นทางไปที่ log.txt:

if not "%1"=="STDOUT_TO_FILE"  %0 STDOUT_TO_FILE %*  >log.txt 2>&1
shift /1

สิ่งนี้ใช้ได้ผลสำหรับฉันขอบคุณ ข้อพิจารณาพิเศษใด ๆ ที่อาจล้มเหลว? (เช่นขนาดเอาต์พุตล้น)
CCarlos

สวัสดีขอบคุณสำหรับคำตอบ! มีวิธีใดในการเปลี่ยนเส้นทางบนคอนโซลด้วย?
Sandeep Singh

3
@echo OFF
[your command] >> [Your log file name].txt

ฉันใช้คำสั่งด้านบนในไฟล์แบตช์ของฉันและมันก็ใช้ได้ ในล็อกไฟล์จะแสดงผลลัพธ์ของคำสั่งของฉัน


0

ซึ่งอาจล้มเหลวในกรณีที่มีอักขระ "เป็นพิษ" ในอินพุต การพิจารณาอินพุตเช่นนี้ IsAnIn ^^^^ ใส่เป็นวิธีที่ดีในการทำความเข้าใจกับสิ่งที่เกิดขึ้น แน่ใจว่ามีกฎว่าสตริงอินพุตต้องอยู่ในเครื่องหมายยกสองคู่ แต่ฉันรู้สึกว่ากฎนี้เป็นกฎที่ถูกต้องก็ต่อเมื่อความหมายของอินพุตเป็นตำแหน่งบนพาร์ติชัน NTFS (อาจเป็นกฎสำหรับ URL I ไม่แน่ใจ) แต่ไม่ใช่กฎสำหรับสตริงอินพุตโดยพลการแน่นอน (เป็น "แนวทางปฏิบัติที่ดี" แต่คุณไม่สามารถนับรวมได้)


0

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

powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^a')
powershell -c "$wshell = New-Object -ComObject wscript.shell; $wshell.SendKeys('^c')
powershell Get-Clipboard > MyLog.txt

มันเป็นพื้นทำการเลือกทั้งหมด -> คัดลอกลงในคลิปบอร์ด -> วางลงในแฟ้มข้อความ

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