Przekierowywanie danych wyjściowych z pliku wsadowego


110

Tworzę plik wsadowy z kilkoma prostymi poleceniami do zbierania informacji z systemu. Plik wsadowy zawiera polecenia, aby uzyskać czas, informacje o adresie IP, użytkowników itp.

Zebrałem wszystkie polecenia w pliku wsadowym i działa, ale chciałbym, aby plik wsadowy po uruchomieniu wyprowadzał wyniki do pliku tekstowego (dziennika). Czy jest polecenie, które mogę dodać do partii, które to zrobi?

Należy pamiętać, że nie chcę uruchamiać partii z cmd, a następnie przekierowywać dane wyjściowe; Chcę przekierować dane wyjściowe z wnętrza wsadu, jeśli to możliwe.

Odpowiedzi:


161

Prosty, naiwny sposób, który jest powolny, ponieważ wielokrotnie otwiera i ustawia wskaźnik pliku na koniec pliku.

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

Lepszy sposób - łatwiejszy do napisania i szybszy, ponieważ plik jest otwierany i pozycjonowany tylko raz.

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

Kolejny dobry i szybki sposób, który otwiera i pozycjonuje plik tylko raz

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

:sub
command1
command2
...
commandN

Edytuj 2020-04-17

Od czasu do czasu możesz chcieć wielokrotnie pisać do dwóch lub więcej plików. Możesz także chcieć wyświetlać różne komunikaty na ekranie. Nadal można to zrobić efektywnie, przekierowując do niezdefiniowanych uchwytów poza blokiem lub podprogramem umieszczonym w nawiasach, a następnie używać &notacji do odwoływania się do już otwartych plików.

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

Zdecydowałem się użyć uchwytów 9 i 8 w odwrotnej kolejności, ponieważ w ten sposób bardziej prawdopodobne jest uniknięcie potencjalnego trwałego przekierowania z powodu błędu projektowego implementacji przekierowania firmy Microsoft podczas wykonywania wielu przekierowań dla tego samego polecenia. Jest to mało prawdopodobne, ale nawet takie podejście może ujawnić błąd, jeśli spróbujesz wystarczająco mocno. Jeśli przygotujesz przekierowanie, na pewno unikniesz problemu.

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

:sub
etc.

2
Uwielbiam rozwiązania, w których mogę ustawić to dla pozostałej części pliku
Sam,

3
Zwróć uwagę, że rozwiązanie wywołania zmienia % 0 ( w tym przypadku na sub ), co może, ale nie musi, być tym, czego chcesz.
Jannes

2
@Jannes - prawda, ale zawsze możesz uzyskać informacje o uruchomionym skrypcie wsadowym, jeśli dodasz modyfikator. Na przykład %~f0zawsze podaje pełną ścieżkę do skryptu wsadowego, nawet jeśli znajduje się w podprocedurze CALLed:.
dbenham

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

2
@Moondra - jest to standardowa składnia wsadowa do wywoływania podprogramu z etykietą w ramach tego samego skryptu. Wykonaj cmd /?lub help cmdz wiersza poleceń konsoli w celu uzyskania dokumentacji. Sztuczka trzeciej metody polega na tym, że przekierowanie w CALL dotyczy wszystkich poleceń w podprogramie CALLed.
dbenham


16

Wiem, że to starszy post, ale ktoś natknie się na niego w wyszukiwarce Google i wygląda na to, że niektóre pytania, które OP zadał w komentarzach, nie zostały szczegółowo omówione. Ponadto, proszę, bądź dla mnie łagodny, ponieważ jest to moja pierwsza odpowiedź opublikowana w SO. :)

Aby przekierować dane wyjściowe do pliku przy użyciu dynamicznie generowanej nazwy pliku, moje podejście do (czytaj: szybkie i brudne) jest drugim rozwiązaniem oferowanym przez @dbenham. Na przykład to:

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

Utworzy plik podobny do tego, który widzisz na tym zrzucie ekranu pliku w katalogu docelowym

To będzie zawierać następujące dane wyjściowe:

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

Pamiętaj również, że to rozwiązanie jest zależne od lokalizacji, więc uważaj, jak i kiedy go używasz.


Dzięki temu było to przydatne. Szybkie pytanie, czy istnieje powód, dla którego używasz .log vs .txt? Czy to robi różnicę?
Moondra

1
@Moondra nie, nie ma. W tym przypadku to tylko semantyka. Nie oznacza to, że nie ma aplikacji, które wymagają / grep na podstawie typu pliku, więc po prostu bądź świadomy tego, czy / jak używane są twoje pliki.
Anthony

9
echo some output >"your logfile"

lub

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

powinien wypełnić rachunek.

Jeśli chcesz uzyskać APPENDdane wyjściowe, użyj >>zamiast >. >uruchomi nowy plik dziennika.


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

Myślę, że to najbardziej elegancki sposób. Dzięki Wesley!
Kiswanij

5

Jest fajny mały program, którego możesz użyć do przekierowania wyjścia do pliku i konsoli

some_command  ^|  TEE.BAT  [ -a ]  filename 


4

Dodaj te dwie linie w górnej części pliku wsadowego, wszystkie stdout i stderr po zostaną przekierowane do log.txt:

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

To zadziałało dla mnie, dzięki. Jakieś szczególne względy, które mogą się nie powieść? (np. przepełnienie rozmiaru wyjściowego)
CCarlos

Cześć, dziękuję za odpowiedź! czy jest jakiś sposób na przekierowanie go również na konsolę?
Sandeep Singh

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

Użyłem powyższego polecenia w moim pliku wsadowym i działa. W pliku dziennika pokazuje wyniki mojego polecenia.


0

Może to się nie powieść w przypadku „toksycznych” znaków na wejściu. Rozważenie takich danych wejściowych, jak this IsAnIn ^^^^, jest dobrym sposobem, aby zrozumieć, co się dzieje. Jasne, że istnieje zasada, że ​​ciąg wejściowy MUSI znajdować się w podwójnych cudzysłowach, ale mam wrażenie, że ta reguła jest prawidłowa tylko wtedy, gdy znaczenie wejścia jest lokalizacją na partycji NTFS (może jest to reguła dla adresów URL I nie jestem pewien). Ale oczywiście nie jest to regułą dla dowolnego ciągu wejściowego (jest to „dobra praktyka”, ale nie można na to liczyć).


0

Dodanie następujących wierszy u dołu pliku wsadowego spowoduje pobranie wszystkiego tak, jak jest wyświetlane w oknie CMD i wyeksportowanie do pliku tekstowego:

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

Zasadniczo wykonuje zaznaczenie wszystkiego -> skopiuj do schowka -> wklej do pliku tekstowego .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.