Odpowiedzi:
Poniższe posty bardzo pomogły, ale nie zrobiły tego, co powiedziałem w moim pytaniu, gdzie muszę przetworzyć całą linię jako całość. Oto, co znalazłem do pracy.
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Słowo kluczowe tokeny oznaczone gwiazdką (*) spowoduje wyciągnięcie całego tekstu z całej linii. Jeśli nie wstawisz gwiazdki, spowoduje to wyciągnięcie tylko pierwszego słowa z linii. Zakładam, że ma to związek ze spacjami.
Doceniam wszystkie posty!
Jeśli na ścieżce pliku znajdują się spacje, musisz użyć usebackq
. Na przykład.
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
Jakieś pomysły jak to udaremnić.?
Z odwołania do wiersza poleceń systemu Windows:
Aby przeanalizować plik, ignorując skomentowane linie, wpisz:
for /F "eol=; tokens=2,3* delims=," %i in (myfile.txt) do @echo %i %j %k
To polecenie analizuje każdą linię w Myfile.txt, ignorując linie rozpoczynające się średnikiem i przekazując drugi i trzeci token z każdej linii do treści FOR (tokeny są rozdzielane przecinkami lub spacjami). Treść instrukcji FOR odwołuje się do% i, aby uzyskać drugi token,% j, aby uzyskać trzeci token, i% k, aby uzyskać wszystkie pozostałe tokeny.
Jeśli podane nazwy plików zawierają spacje, użyj cudzysłowów wokół tekstu (na przykład „Nazwa pliku”). Aby użyć cudzysłowu, musisz użyć usebackq. W przeciwnym razie znaki cudzysłowu są interpretowane jako definiujące dosłowny ciąg do analizy.
Nawiasem mówiąc, plik pomocy wiersza polecenia można znaleźć w większości systemów Windows pod adresem:
"C:\WINDOWS\Help\ntcmds.chm"
usebackq
” : for /f "usebackq" %%a in ("Z:\My Path Contains Spaces\xyz\abc.txt")
W pliku wsadowym MUSISZ użyć %%
zamiast %
: (Typ 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
Co to robi: „do call: proces %% i %% j %% k” na końcu polecenia for przekazuje informacje uzyskane w poleceniu for z pliku myfile.txt do podprogramu „process”.
Kiedy używasz polecenia for w programie wsadowym, musisz użyć podwójnych znaków% dla zmiennych.
Poniższe wiersze przekazują te zmienne z polecenia for do podprogramu procesu i umożliwiają przetwarzanie tych informacji.
set VAR1=%1
set VAR2=%2
set VAR3=%3
Mam kilka całkiem zaawansowanych zastosowań tej dokładnej konfiguracji, którą chętnie podzielę się, jeśli będą potrzebne dalsze przykłady. Oczywiście dodaj EOL lub Delims.
Poprawianie pierwszej odpowiedzi „FOR / F ..”: Musiałem wywołać wykonanie każdego skryptu wymienionego w MyList.txt, więc zadziałało dla mnie:
for /F "tokens=*" %A in (MyList.txt) do CALL %A ARG1
--LUB, jeśli chcesz to zrobić przez wiele linii:
for /F "tokens=*" %A in (MuList.txt) do (
ECHO Processing %A....
CALL %A ARG1
)
Edycja: Powyższy przykład dotyczy wykonania pętli FOR z wiersza polecenia; ze skryptu wsadowego należy dodać dodatkowy%, jak pokazano poniżej:
---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---
@ Odpowiedź MrKrausa jest pouczająca. Ponadto pozwól mi dodać, że jeśli chcesz załadować plik znajdujący się w tym samym katalogu, co plik wsadowy, poprzedź nazwę pliku za pomocą% ~ dp0. Oto przykład:
cd /d %~dp0
for /F "tokens=*" %%A in (myfile.txt) do [process] %%A
Uwaga: Jeśli nazwa lub katalog pliku (np. Mój plik.txt w powyższym przykładzie) ma spację (np. „Mój plik.txt” lub „c: \ Program Files”), użyj:
for /F "tokens=*" %%A in ('type "my file.txt"') do [process] %%A
, ze słowem kluczowym type wywołującym type
program, który wyświetla zawartość pliku tekstowego. Jeśli nie chcesz ponosić nakładów związanych z wywoływaniem polecenia type, zmień katalog na katalog pliku tekstowego. Zauważ, że typ jest nadal wymagany dla nazw plików ze spacjami.
Mam nadzieję, że to komuś pomoże!
**cd /d %~dp0**
przed pętlą for. Zapewniłoby to odniesienie do pliku w katalogu, w którym znajduje się plik wsadowy. Dzięki za obserwację
type
Walkaround
type
obejść problemu, musiałem zacytować swoją nazwę pliku, ponieważ jest on w innym katalogu, który zawiera spacje (cholera Program Files
). Dostaję błądThe system cannot find the file `type.
Przyjęta odpowiedź jest dobra, ale ma dwa ograniczenia.
Zrzuca puste linie i linie zaczynające się od;
Aby odczytać wiersze dowolnej treści, potrzebujesz techniki przełączania opóźnionego rozszerzenia.
@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 służy do poprzedzania każdej linii numerem linii i dwukropkiem, więc puste linie nie są już puste.
DelayedExpansion należy wyłączyć podczas uzyskiwania dostępu do %%a
parametru, w przeciwnym razie wykrzykniki !
i znaki ^
zostaną utracone, ponieważ mają one specjalne znaczenie w tym trybie.
Ale aby usunąć numer linii z linii, należy włączyć opóźnione rozszerzenie.
set "var=!var:*:=!"
usuwa wszystkie do pierwszego dwukropka (użycie delims=:
spowoduje usunięcie wszystkich dwukropków na początku linii, nie tylko tego z findstr).
Endlocal ponownie wyłącza opóźnione rozwinięcie dla następnej linii.
Jedynym ograniczeniem jest teraz limit długości linii wynoszący ~ 8191, ale wydaje się, że nie ma sposobu na obejście tego.
setlocal
na polecenie. Kiedy uruchamiam kod na CMD, dostaję! Var! zamiast pustych miejsc. Jak naprawić?
Oto plik nietoperza, który napisałem, aby wykonać wszystkie skrypty SQL w folderze:
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
Jeśli masz NT-rodziny Windows (jedna z cmd.exe
jak skorupy), spróbuj polecenia FOR / F .
Akceptowana odpowiedź przy użyciu cmd.exe
i
for /F "tokens=*" %F in (file.txt) do whatever "%F" ...
działa tylko dla „normalnych” plików. Zawodzi żałośnie przy dużych plikach.
W przypadku dużych plików może być konieczne użycie programu Powershell i czegoś takiego:
[IO.File]::ReadLines("file.txt") | ForEach-Object { whatever "$_" }
lub jeśli masz wystarczającą ilość pamięci:
foreach($line in [System.IO.File]::ReadLines("file.txt")) { whatever "$line" }
Działa to dla mnie z plikiem 250 MB zawierającym ponad 2 miliony linii, w którym for /F ...
polecenie utknęło po kilku tysiącach linii.
Różnice między foreach
i ForEach-Object
zobacz Poznanie ForEach i ForEach-Object .
(kredyty: Czytaj plik linia po linii w PowerShell )
Zmodyfikowane przykłady tutaj, aby wyświetlić listę naszych aplikacji Railsowych na Heroku - dzięki!
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
Pełny kod tutaj .
for /f "tokens=1" %%i in ('find /v "=" heroku_apps.txt ^| find /v ".TXT" ^| findstr /r /v /c:"^$"') do...
(Zwróć uwagę na dodanie ^
for
Aby wydrukować wszystkie wiersze w pliku tekstowym z wiersza poleceń (z rozszerzeniem opóźnionym):
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!)
Działa z wiodącymi białymi spacjami, pustymi liniami i białymi liniami.
Testowany na Win 10 CMD
]]]
linie wiodące z linii, druga próbka upuszcza puste linie i linie zaczynające się od spacji
delims
jeśli dowolne wiersze w pliku tekstowym zaczynają się od ]
np. zamień na jakiś znak, który tego nie robi, lub na znak kontrolny, taki jak Backspace lub Bell; zwykle nie występują w plikach tekstowych. Powodem delims=]
jest usunięcie zastępcze stworzone przez /n
z find
poleceniem, aby zachować puste linie.
%%A
ze%A
w powyższym poleceniu. W przeciwnym razie dostaniesz%%A was unexpected at this time.
.