आप विंडोज़ बैच फ़ाइल का उपयोग करके टेक्स्ट फ़ाइल में प्रत्येक पंक्ति के माध्यम से कैसे लूप करते हैं?


244

मैं जानना चाहूंगा कि विंडोज बैच फ़ाइल का उपयोग करके टेक्स्ट फ़ाइल में प्रत्येक पंक्ति के माध्यम से कैसे लूप किया जाए और पाठ की प्रत्येक पंक्ति को उत्तराधिकार में संसाधित किया जाए।

जवाबों:


304

नीचे दिए गए पोस्टों ने बहुत मदद की, लेकिन मैंने अपने प्रश्न में ऐसा नहीं किया, जहां मुझे पूरी लाइन को एक पूरे के रूप में संसाधित करने की आवश्यकता थी। यहाँ मुझे काम करने के लिए मिला है।

for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

तारांकन चिह्न (*) वाला टोकन कीवर्ड पूरी पंक्ति के लिए सभी पाठ को खींच लेगा। यदि आप तारांकन में नहीं डालते हैं तो यह केवल लाइन पर पहला शब्द खींचेगा। मुझे लगता है कि यह रिक्त स्थान के साथ क्या करना है।

TechNet पर कमांड के लिए

मैं सभी पदों की सराहना करता हूं!


यदि आपके फ़ाइल पथ में स्थान हैं, तो आपको उपयोग करने की आवश्यकता है usebackq। उदाहरण के लिए।

for /F "usebackq tokens=*" %%A in ("my file.txt") do [process] %%A

37
एक छोटी सी अतिरिक्त: कमांड लाइन से इस काम सहभागी बनाने के लिए, की जगह %%Aके साथ %Aउपरोक्त आदेश में। नहीं तो तुम पाओगे %%A was unexpected at this time.
vadipp

16
FYI करें, यदि आपको एक बहु-पंक्ति कमांड करने की आवश्यकता है, तो "DO" के बाद आप एक खुला कोष्ठक डाल सकते हैं "(" और कुछ पंक्तियों के बाद, इसे बंद कोष्ठक के साथ समाप्त करें ")" - और आप बस अपना कोड डाल सकते हैं उन के अंदर ब्लॉक करें (अपने स्वाद के लिए प्रेरित)।
BrainSlugs83

3
उस पैटर्न के लिए धन्यवाद। मैं ने पाया है कि मैं कोट ( ") एक फ़ाइल नाम के आसपास नहीं डाल सकते -। रिक्त स्थान के साथ फ़ाइल नाम के लिए बस मुझे फ़ाइल नाम देता है जैसे for /F "tokens=*" %%A in ("myfile.txt") do echo A = %%A-> A = myfile.txtयह कैसे को विफल करने के कोई भी विचार।?
होगा

1
सुनिश्चित करें कि आप जो फ़ाइल काम कर रहे हैं वह ANSI या UTF8 में एन्कोडेड है। मैं अपने सिर को खरोंच रहा था कि यह तब तक काम क्यों नहीं कर रहा था जब तक कि मैंने फ़ाइल को TYPE कमांड का उपयोग करके देखने की कोशिश नहीं की थी और आउटपुट वह नहीं था जिसकी मुझे उम्मीद थी। इस बिंदु पर मैंने देखा कि किसी कारण से फाइल "UCS-2 BE BOM" में एनकोड हो गई थी!
डेन स्टीवंस

1
यह इंगित करने योग्य है कि आपके लूप में इंडेक्स पैरामीटर एक एकल वर्ण होना चाहिए। इसलिए उदाहरण के लिए %% मैं ठीक हूँ लेकिन %% अनुक्रमणिका विफल हो जाएगी।
विंसेंट

59

Windows कमांड लाइन संदर्भ से:

किसी फ़ाइल को पार्स करने के लिए, टिप्पणी की गई लाइनों को अनदेखा करें:

for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k

यह कमांड Myfile.txt में प्रत्येक लाइन को पार्स करता है, जो एक सेमीकोलन से शुरू होने वाली लाइनों को अनदेखा करता है और प्रत्येक बॉडी से दूसरे बॉडी (टोकन को कॉमा या स्पेस द्वारा सीमांकित किया जाता है) से दूसरे और तीसरे टोकन को पार करता है। फॉर स्टेटमेंट का शरीर% i को दूसरा टोकन प्राप्त करने के लिए,% j को तीसरा टोकन पाने के लिए, और% k को शेष सभी टोकन प्राप्त करने के लिए संदर्भित करता है।

यदि आपके द्वारा आपूर्ति की जाने वाली फ़ाइल नाम में रिक्त स्थान हैं, तो पाठ के चारों ओर उद्धरण चिह्नों का उपयोग करें (उदाहरण के लिए, "फ़ाइल नाम")। उद्धरण चिह्नों का उपयोग करने के लिए, आपको उपयोग करना होगा। अन्यथा, उद्धरण चिह्नों को पार्स करने के लिए शाब्दिक स्ट्रिंग को परिभाषित करने के रूप में व्याख्या की जाती है।

वैसे, आप अधिकांश विंडोज सिस्टम पर कमांड-लाइन हेल्प फ़ाइल पा सकते हैं:

 "C:\WINDOWS\Help\ntcmds.chm"

8
करने के लिए स्पष्ट "उद्धरण चिह्नों का उपयोग करने के लिए, आप का उपयोग करना चाहिए usebackq" : for /f "usebackq" %%a in ("Z:\My Path Contains Spaces\xyz\abc.txt")
drzaus

35

एक बैच फ़ाइल में आप इसके बजाय उपयोग करना चाहिए : (प्रकार )%%%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

यह क्या करता है: "for call: process %% i %% j %% k" कमांड के अंत में myfile.txt से कमांड के लिए अधिग्रहीत सूचना "प्रक्रिया" 'सबरूटीन' को पास करता है।

जब आप बैच प्रोग्राम में कमांड के लिए उपयोग कर रहे हैं, तो आपको चर के लिए दोहरे% संकेतों का उपयोग करने की आवश्यकता है।

निम्न लाइनें उन चर को कमांड से प्रक्रिया 'सब रुटीन' के लिए पास करती हैं और आपको इस जानकारी को संसाधित करने की अनुमति देती हैं।

set VAR1=%1
 set VAR2=%2
 set VAR3=%3

मेरे पास इस सटीक सेटअप के कुछ बहुत उन्नत उपयोग हैं जिन्हें मैं साझा करने के लिए तैयार रहूंगा यदि आगे के उदाहरणों की आवश्यकता हो। पाठ्यक्रम की जरूरत के अनुसार अपने EOL या Delims में जोड़ें।


27

पहले "फॉर / एफ .." उत्तर में सुधार: मुझे क्या करना था, जो MyList.txt में सूचीबद्ध प्रत्येक स्क्रिप्ट को निष्पादित करने के लिए था, इसलिए इसने मेरे लिए काम किया:

for /F "tokens=*" %A in  (MyList.txt) do CALL %A ARG1

--OR, यदि आप इसे कई लाइन पर करना चाहते हैं:

for /F "tokens=*" %A in  (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)

संपादित करें: ऊपर दिया गया उदाहरण कमांड-प्रॉम्प्ट से लूप को निष्पादित करने के लिए है; बैच-स्क्रिप्ट से, अतिरिक्त% जोड़ने की आवश्यकता है, जैसा कि नीचे दिखाया गया है:

---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---

21

@ MrKraus का उत्तर शिक्षाप्रद है। इसके अलावा, मुझे जोड़ने दें कि यदि आप एक ही निर्देशिका में स्थित फ़ाइल को बैच फ़ाइल के रूप में लोड करना चाहते हैं , तो फ़ाइल का नाम% ~ dp0 के साथ उपसर्ग करें। यहाँ एक उदाहरण है:

cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A

NB:: यदि आपकी फ़ाइल का नाम या निर्देशिका (उदाहरण के लिए उपरोक्त उदाहरण में myfile.txt) में स्थान है (उदाहरण के लिए 'my file.txt' या 'c: \ Program Files'), का उपयोग करें:

for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A

, प्रोग्राम को टाइप करने वाले कीवर्ड के साथ type, जो एक टेक्स्ट फ़ाइल की सामग्री को प्रदर्शित करता है। यदि आप टाइप कमांड को कॉल करने के ओवरहेड को भुगतना नहीं चाहते हैं, तो आपको निर्देशिका को टेक्स्ट फ़ाइल की निर्देशिका में बदलना चाहिए। ध्यान दें कि रिक्त स्थान के साथ फ़ाइल नाम के लिए अभी भी आवश्यक है।

मुझे उम्मीद है इससे किसी को सहायता मिलेगी!


फ़ाइल नाम को उपसर्ग करने की कोई आवश्यकता नहीं है क्योंकि बैच फ़ाइल डिफ़ॉल्ट रूप से वर्तमान फ़ोल्डर में दिखाई देगी।
foxidrive

1
@foxidrive: ठीक है, मैं आपको सुनता हूँ। हालांकि देखभाल की जानी चाहिए। उदाहरण के लिए यदि कोई निर्देशिका बदली गई थी, तो वह उस निर्देशिका में दिखेगी, जिसमें एक बैच फ़ाइल होती है। समाधान तब **cd /d %~dp0**लूप के लिए कॉल किया जाएगा । यह सुनिश्चित करेगा कि आप उस निर्देशिका में एक फ़ाइल का जिक्र कर रहे हैं जो बैच फ़ाइल में है। अवलोकन के लिए धन्यवाद
Marvin Thobejane

2
Thx और +1 के लिए typewalkaround
halex

मुझे typeकाम करने के आस-पास काम नहीं मिल सकता है , मुझे अपना फ़ाइल नाम उद्धृत करना होगा क्योंकि यह एक अलग निर्देशिका में है जिसमें रिक्त स्थान हैं (लानत है आप Program Files)। मुझे एक त्रुटि मिल रही हैThe system cannot find the file `type.
स्क्रबर

1
@ सागर, क्या आपको सही उद्धरण मिला है? यह एक 'नहीं' होना चाहिए। अपने कीबोर्ड पर यह रूप में एक ही कुंजी पर है @
FrinkTheBrave

18

स्वीकृत उत्तर अच्छा है, लेकिन इसकी दो सीमाएँ हैं।
यह खाली रेखाओं और रेखाओं से शुरू होता है;

किसी भी सामग्री की पंक्तियों को पढ़ने के लिए, आपको विलंबित टॉगलिंग टेक्निक की आवश्यकता है।

@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=:केवल एक लाइन की शुरुआत में सभी कॉलोनों को हटा देगा, न कि केवल एक बार)।
एंडलोक अगली पंक्ति के लिए फिर से विलंबित विस्तार को अक्षम करता है।

केवल सीमा अब ~ 8191 की लाइन लंबाई सीमा है, लेकिन इसे दूर करने का कोई तरीका नहीं है।


विन 10 setlocalकमांडलाइन पर अनुमति नहीं देता है। जब मैं CMD पर कोड चलाता हूं, तो मुझे मिल जाता है! खाली के बजाय। कैसे ठीक करना है?
जोम्बा

प्रसंस्करण से पहले अधिकतम लाइन लंबाई 8190 की फ़ाइलों को विभाजित करने के लिए लाइन की लंबाई सीमा को विभाजित किया जा सकता है। फिर एक फ़ाइल पर पुनर्संयोजन करें।
जोम्बा

14

या, आप उद्धरण में विकल्पों को बाहर कर सकते हैं:

FOR /F %%i IN (myfile.txt) DO ECHO %%i

1
एक-दूसरे %% के बगल में दो प्रतिशत संकेतों को एक कमांड (एक बैच फ़ाइल नहीं) में एकल प्रतिशत संकेत की तरह माना जाता है।
पॉल

9

यहाँ एक बैट फाइल है जिसे मैंने एक फ़ोल्डर में सभी 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


6

का उपयोग कर स्वीकार किए जाते हैं 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" } 

इसने मेरे लिए २५० लाइनों वाली २५० एमबी फाइल के साथ काम किया, जहां for /F ...कुछ हजार लाइनों के बाद कमांड अटक गई।

के बीच के अंतर के लिए foreachऔर ForEach-Object, ForEach और ForEach-Object को जानना देखें ।

(क्रेडिट: पॉवरशेल में लाइन द्वारा फ़ाइल लाइन पढ़ें )


1

हरकोलोक पर हमारे रेल एप्लिकेशन को सूचीबद्ध करने के लिए यहां दिए गए उदाहरण - धन्यवाद!

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और सीधे कमांड प्रोसेसर को नहीं)
user66001

0

कमांड लाइन से पाठ फ़ाइल में सभी लाइनों को प्रिंट करने के लिए (विलंबित विस्तार के साथ):

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 पर परीक्षण किया गया


भगवान कोशिश करते हैं, लेकिन आपका पहला नमूना ]]]लाइनों से अग्रणी को निकालता है , दूसरा नमूना खाली रेखाओं और रेखाओं को अंतरिक्ष से शुरू करता है
jeb

दूसरा एक रिक्त लाइनों को हटाने के लिए है। delimsयदि पाठ फ़ाइल में कोई रेखाएँ ]उदाहरण के लिए शुरू होती हैं तो 1 को संशोधित किया जा सकता है । कुछ ऐसे चरित्र से प्रतिस्थापित करें, जो नियंत्रण या बैकस्पेस या घंटी की तरह एक नियंत्रण चरित्र नहीं है; वे आम तौर पर पाठ फ़ाइलों में नहीं पाए जाते हैं। के लिए कारण delims=]द्वारा बनाई प्लेसहोल्डर दूर करने के लिए है /nके findरिक्त लाइनों की रक्षा करने के आदेश।
जोम्बा

@ जेब: ब्रैकेट]]] समस्या तय हो गई है। टेक्स्ट फ़ाइल में सभी लाइनों को प्रिंट करने के लिए, अपडेट देखें। विन 10 CMD पर भी काम करता है।
जोम्बा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.