ฉันต้องการทราบวิธีวนรอบแต่ละบรรทัดในไฟล์ข้อความโดยใช้ไฟล์แบตช์ Windows และประมวลผลแต่ละบรรทัดอย่างต่อเนื่อง
ฉันต้องการทราบวิธีวนรอบแต่ละบรรทัดในไฟล์ข้อความโดยใช้ไฟล์แบตช์ Windows และประมวลผลแต่ละบรรทัดอย่างต่อเนื่อง
คำตอบ:
โพสต์ด้านล่างช่วยได้มาก แต่ไม่ได้ทำในสิ่งที่ฉันระบุไว้ในคำถามที่ฉันต้องการประมวลผลทั้งบรรทัดโดยรวม นี่คือสิ่งที่ฉันพบว่าทำงาน
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
คำหลักโทเค็นที่มีเครื่องหมายดอกจัน (*) จะดึงข้อความทั้งหมดสำหรับทั้งบรรทัด หากคุณไม่ใส่เครื่องหมายดอกจันระบบจะดึงเฉพาะคำแรกบนบรรทัด ฉันคิดว่ามันเกี่ยวข้องกับช่องว่าง
ฉันขอขอบคุณโพสต์ทั้งหมด!
usebackq
หากมีช่องว่างในเส้นทางไฟล์ของคุณคุณจะต้องใช้ ตัวอย่างเช่น.
for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A
for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A
-> A = myfile.txt
ความคิดใดวิธีการขัดขวางนี้.
จากการอ้างอิงบรรทัดคำสั่ง Windows:
ในการแยกวิเคราะห์ไฟล์โดยไม่สนใจบรรทัดที่คอมเม้นต์ให้พิมพ์:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k
คำสั่งนี้วิเคราะห์คำแต่ละบรรทัดใน Myfile.txt โดยไม่สนใจบรรทัดที่ขึ้นต้นด้วยเครื่องหมายอัฒภาคและส่งโทเค็นที่สองและสามจากแต่ละบรรทัดไปยัง FOR body (โทเค็นถูกคั่นด้วยเครื่องหมายจุลภาคหรือช่องว่าง) เนื้อความของคำสั่ง FOR อ้างอิง% i เพื่อรับโทเค็นที่สอง,% j เพื่อรับโทเค็นที่สามและ% k เพื่อรับโทเค็นที่เหลือทั้งหมด
หากชื่อไฟล์ที่คุณระบุมีช่องว่างให้ใช้เครื่องหมายคำพูดล้อมรอบข้อความ (เช่น "ชื่อไฟล์") ในการใช้เครื่องหมายคำพูดคุณต้องใช้ usebackq มิฉะนั้นเครื่องหมายคำพูดจะถูกตีความว่าเป็นการกำหนดสตริงตัวอักษรที่จะแยกวิเคราะห์
อย่างไรก็ตามคุณสามารถค้นหาไฟล์วิธีใช้บรรทัดคำสั่งบนระบบ Windows ส่วนใหญ่ได้ที่:
"C:\WINDOWS\Help\ntcmds.chm"
ในไฟล์แบทช์คุณต้องใช้%%
แทน%
: (Type help for
)
for /F "tokens=1,2,3" %%i in (myfile.txt) do call :process %%i %%j %%k
goto thenextstep
:process
set VAR1=%1
set VAR2=%2
set VAR3=%3
COMMANDS TO PROCESS INFORMATION
goto :EOF
สิ่งนี้จะทำอะไร: กระบวนการ "do call: process %% i %% j %% k" ที่ส่วนท้ายของคำสั่ง for ส่งผ่านข้อมูลที่ได้รับในคำสั่ง for จาก myfile.txt ไปยังรูทีนย่อย "process" '
เมื่อคุณใช้คำสั่ง for ในโปรแกรมแบทช์คุณต้องใช้เครื่องหมาย% คู่สำหรับตัวแปร
บรรทัดต่อไปนี้ส่งผ่านตัวแปรเหล่านั้นจากคำสั่ง for ถึงกระบวนการ 'รูทีนย่อย' และอนุญาตให้คุณประมวลผลข้อมูลนี้
set VAR1=%1
set VAR2=%2
set VAR3=%3
ฉันมีการใช้งานที่ล้ำสมัยของการตั้งค่าที่แน่นอนนี้ซึ่งฉันยินดีที่จะแบ่งปันหากต้องการตัวอย่างเพิ่มเติม เพิ่มใน EOL หรือ Delims ของคุณตามที่ต้องการแน่นอน
การปรับปรุงคำตอบ "FOR / F .. " ครั้งแรก: สิ่งที่ฉันต้องทำคือเรียกใช้งานสคริปต์ทุกรายการใน MyList.txt ดังนั้นจึงใช้งานได้สำหรับฉัน:
for /F "tokens=*" %A in (MyList.txt) do CALL %A ARG1
- หรือหากคุณต้องการทำหลายบรรทัด:
for /F "tokens=*" %A in (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
แก้ไข: ตัวอย่างที่ระบุข้างต้นสำหรับการดำเนินการ FOR วนจาก command-prompt; จากชุดสคริปต์ต้องเพิ่ม% พิเศษดังที่แสดงด้านล่าง:
---START of MyScript.bat---
@echo off
for /F "tokens=*" %%A in ( MyList.TXT) do (
ECHO Processing %%A....
CALL %%A ARG1
)
@echo on
;---END of MyScript.bat---
@ คำตอบ MrKraus เป็นคำแนะนำ เพิ่มเติมให้ฉันเพิ่มว่าถ้าคุณต้องการโหลดไฟล์ที่อยู่ในไดเรกทอรีเดียวกันกับไฟล์แบตช์คำนำหน้าชื่อไฟล์ด้วย% ~ dp0 นี่คือตัวอย่าง:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
หมายเหตุ:หากชื่อไฟล์หรือไดเรกทอรีของคุณ (เช่น myfile.txt ในตัวอย่างด้านบน) มีช่องว่าง (เช่น 'my file.txt' หรือ 'c: \ Program Files') ให้ใช้:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
ด้วยคีย์เวิร์ดtype ที่เรียกใช้type
โปรแกรมซึ่งแสดงเนื้อหาของไฟล์ข้อความ หากคุณไม่ต้องการประสบกับค่าใช้จ่ายในการเรียกคำสั่ง type คุณควรเปลี่ยนไดเรกทอรีเป็นไดเรกทอรีของไฟล์ข้อความ โปรดทราบว่าประเภทนั้นยังจำเป็นสำหรับชื่อไฟล์ที่มีช่องว่าง
ฉันหวังว่านี่จะช่วยให้ใครบางคน!
**cd /d %~dp0**
ก่อน for for loop สิ่งนี้จะทำให้แน่ใจว่าคุณกำลังอ้างอิงไฟล์ในไดเรกทอรีที่มีไฟล์แบตช์อยู่ขอบคุณที่สังเกต
type
walkaround
type
ทำงานได้ฉันต้องอ้างชื่อไฟล์ของฉันเพราะมันอยู่ในไดเรกทอรีอื่นที่มีการเว้นวรรค (ประณามคุณProgram Files
) ฉันได้รับข้อผิดพลาดThe system cannot find the file `type.
คำตอบที่ยอมรับนั้นดี แต่มีข้อ จำกัด สองประการ
มันจะปล่อยบรรทัดว่างและบรรทัดที่ขึ้นต้นด้วย;
หากต้องการอ่านบรรทัดของเนื้อหาใด ๆ คุณต้องมีการสลับเทคนิคการขยายการเลื่อน
@echo off
SETLOCAL DisableDelayedExpansion
FOR /F "usebackq delims=" %%a in (`"findstr /n ^^ text.txt"`) do (
set "var=%%a"
SETLOCAL EnableDelayedExpansion
set "var=!var:*:=!"
echo(!var!
ENDLOCAL
)
Findstr ใช้เพื่อนำหน้าแต่ละบรรทัดด้วยหมายเลขบรรทัดและโคลอนดังนั้นบรรทัดว่างจะไม่ว่างเปล่าอีกต่อไป
DelayedExpansion จำเป็นต้องปิดการใช้งานเมื่อเข้าถึง%%a
พารามิเตอร์เครื่องหมายอัศเจรีย์!
และเครื่องหมายอื่น^
จะหายไปเนื่องจากมีความหมายพิเศษในโหมดนั้น
แต่หากต้องการลบหมายเลขบรรทัดออกจากบรรทัดจำเป็นต้องเปิดใช้งานส่วนขยายที่ล่าช้า
set "var=!var:*:=!"
ลบทั้งหมดจนถึงโคลอนแรก (การใช้delims=:
จะลบโคลอนทั้งหมดที่จุดเริ่มต้นของบรรทัดด้วยไม่ใช่เฉพาะโคลอนจาก findstr)
endlocal ปิดใช้งานการขยายตัวที่ล่าช้าอีกครั้งสำหรับบรรทัดถัดไป
ขณะนี้ข้อ จำกัด เพียงอย่างเดียวคือขีดจำกัดความยาวบรรทัดที่ ~ 8191 แต่ดูเหมือนว่าจะไม่มีทางเอาชนะได้
setlocal
กับ commandline เมื่อฉันเรียกใช้รหัสใน CMD ฉันจะได้รับ! var! แทนช่องว่าง จะแก้ไขอย่างไร
หรือคุณอาจยกเว้นตัวเลือกในเครื่องหมายคำพูด:
FOR /F %%i IN (myfile.txt) DO ECHO %%i
นี่คือไฟล์ bat ที่ฉันเขียนเพื่อรันสคริปต์ SQL ทั้งหมดในโฟลเดอร์:
REM ******************************************************************
REM Runs all *.sql scripts sorted by filename in the current folder.
REM To use integrated auth change -U <user> -P <password> to -E
REM ******************************************************************
dir /B /O:n *.sql > RunSqlScripts.tmp
for /F %%A in (RunSqlScripts.tmp) do osql -S (local) -d DEFAULT_DATABASE_NAME -U USERNAME_GOES_HERE -P PASSWORD_GOES_HERE -i %%A
del RunSqlScripts.tmp
หากคุณมี NT-Windows ครอบครัว (หนึ่งกับcmd.exe
เป็นเปลือก) ลองคำสั่งสำหรับ / F
anwser ที่ยอมรับโดยใช้cmd.exe
และ
for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
ใช้งานได้กับไฟล์ "ปกติ" เท่านั้น มันล้มเหลวอย่างน่าสังเวชด้วยไฟล์ขนาดใหญ่
สำหรับไฟล์ขนาดใหญ่คุณอาจต้องใช้ Powershell และสิ่งนี้:
[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
หรือถ้าคุณมีหน่วยความจำเพียงพอ:
foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" }
สิ่งนี้ใช้ได้กับฉันด้วยไฟล์ 250 MB ที่มีมากกว่า 2 ล้านบรรทัดซึ่งfor /F ...
คำสั่งติดค้างหลังจากสองสามพันบรรทัด
สำหรับความแตกต่างระหว่างforeach
และForEach-Object
ดูจะได้รู้ว่า ForEach และ ForEach
(เครดิต: อ่านไฟล์ทีละบรรทัดใน PowerShell )
ตัวอย่างดัดแปลงที่นี่เพื่อแสดงรายการแอพ Rails ของเราใน Heroku - ขอบคุณ!
cmd /C "heroku list > heroku_apps.txt"
find /v "=" heroku_apps.txt | find /v ".TXT" | findstr /r /v /c:"^$" > heroku_apps_list.txt
for /F "tokens=1" %%i in (heroku_apps_list.txt) do heroku run bundle show rails --app %%i
for /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do...
(โปรดสังเกตว่าการเพิ่มของ^
เคยใช้เพื่อหลบหนีไปป์ดังนั้นมันจะถูกส่งผ่านไปยังfor
โปรเซสเซอร์โดยตรงและไม่ได้โดยตรง)
หากต้องการพิมพ์บรรทัดทั้งหมดในไฟล์ข้อความจากบรรทัดคำสั่ง (ที่มีExpansionล่าช้า):
set input="path/to/file.txt"
for /f "tokens=* delims=[" %i in ('type "%input%" ^| find /v /n ""') do (
set a=%i
set a=!a:*]=]!
echo:!a:~1!)
ทำงานร่วมกับช่องว่างนำหน้าบรรทัดว่างบรรทัดว่าง
ทดสอบกับ Win 10 CMD
]]]
จากบรรทัดตัวอย่างที่สองจะปล่อยบรรทัดว่างและบรรทัดที่ขึ้นต้นด้วย space
delims
บรรทัดแรกสามารถแก้ไขได้หากบรรทัดใด ๆ ในไฟล์ข้อความเริ่มต้นด้วย]
เช่น แทนที่ด้วยอักขระบางตัวที่ไม่ได้หรือตัวควบคุมเช่น backspace หรือเบลล์; โดยปกติจะไม่พบในไฟล์ข้อความ เหตุผลdelims=]
คือการเอาตัวยึดที่สร้างขึ้นโดย/n
ในfind
คำสั่งเพื่อรักษาบรรทัดว่าง
%%A
ด้วย%A
ในคำสั่งดังกล่าว%%A was unexpected at this time.
มิฉะนั้นคุณจะได้รับ