Uzyskaj drugi wiersz wyniku z polecenia

1

Mam wiele plików z jsonrozszerzeniem w katalogu. Są one używane do generowania niektórych innych plików, ale powinno to nastąpić tylko wtedy, gdy jsonpliki się zmieniły.

Do tej pory mam następujący skąpy skrypt:

for %%f in (*.json) do (
            echo %%f
            certutil -hashfile %%f SHA256 >> HASH.txt
    )

Przeglądam wszystkie jsonpliki, generuję wartość skrótu SHA256 dla każdego, a następnie dołączam ją do HASH.txtpliku za pomocą certUitl. Mój problem pochodzi z danych wyjściowych zwracanych przez narzędzie, a mianowicie (mam niemiecki Win 10):

SHA256-Hash der Datei BLAH.json:
d8338f6f2649bcb358e56e0973fe2f5a886771e0debbdb0fefef35976a1b88ca
CertUtil: -hashfile-Befehl wurde erfolgreich ausgeführt.

Chciałbym zdobyć wartość skrótu. W powyższym przykładzie byłoby to

d8338f6f2649bcb358e56e0973fe2f5a886771e0debbdb0fefef35976a1b88ca

który jest drugim wierszem wyniku. Szukałem rozwiązania, w jaki sposób uzyskać tylko określony wiersz wyniku i pomijać resztę, ale wszystko, co mogłem znaleźć, dotyczyło plików tekstowych, które nie wydają się zbyt pomocne. Jakieś pomysły, jak to zrobić?

rbaleksandar
źródło
Brzmi jak praca dla findstr .
gronostaj

Odpowiedzi:

1

Możesz ułatwić sobie życie, filtrując dane wyjściowe certutil za pomocą
findstr /V ":"
skrótu, który jest jedyną linią bez dwukropka.

@Echo off
(for %%f in (*.json) do certutil -hashfile "%%~f" SHA256 | findstr /V ":" 
)> HASH.txt

Inne podejście polegające na otrzymaniu dowolnego określonego numeru linii:

@Echo off
Set Line=2
(for %%f in (*.json) do for /f "tokens=1,* delims=:" %%A in (
  'certutil -hashfile "%%~f" SHA256 ^| findstr /n "^" ^|findstr "^%Line%:"'
) Do echo %%B) > HASH.txt

Kolejny wariant przechowujący skrót i pełną nazwę pliku w HASHjson.txt

@Echo off
Set "Hash=HASHjson.txt"
For %%F in (*.json) do For /f %%A in (
    'certutil -hashfile "%%~F" SHA256 ^| findstr /V ":"'
) Do Findstr "^%%A" "%HASH%" >NUL 2>&1 && (
    Echo HASH %%A already present in %Hash%
) || (
    Echo Add %%A %%~fF
    >>"%Hash%" Echo %%A %%~fF
)

Przykładowy przebieg:

> hashjson.cmd
Add eaf7df6fd6fe0719b6eafef8e4f74070684125822d03e6642a7e42fb425b442b A:\AIMavJ5IlpEmYCN.json
Add 24f1508e5e4a920b3233a37ce959e1e4f3fcd2a4ed90daec7879bc58af2a3a98 A:\AQ0G8KFw6KIj0JR.json

> hashjson.cmd
HASH eaf7df6fd6fe0719b6eafef8e4f74070684125822d03e6642a7e42fb425b442b already present in HASHjson.txt
HASH 24f1508e5e4a920b3233a37ce959e1e4f3fcd2a4ed90daec7879bc58af2a3a98 already present in HASHjson.txt
LotPings
źródło
Jednowierszowe rozwiązanie nie pozwala na dalsze dostosowywanie tego, co jest dołączane do pliku. Ponownie przemyślałem moją sytuację i wydaje się, że <filename>.json : <hash-value>fajne byłoby również przechowywanie nazwy pliku (coś podobnego ), ponieważ będę mógł później sprawdzić, czy prefiks ( <filename>.json) z każdej linii w pliku tekstowym faktycznie istnieje jako plik system plików i NASTĘPNIE obliczają ponownie wartość skrótu. Zwłaszcza w przypadku wielu plików wydaje się to być szybszym podejściem zamiast ślepego „mieszania” wszystkich plików za każdym razem. W takim przypadku lepiej jest przechowywać dane wyjściowe w zmiennej.
rbaleksandar
Dodano wariant przechowujący skrót i sprawdzenie nazwy pliku, jeśli skrót jest już obecny.
LotPings,
Dostosuję to (tak, że porównywana jest nazwa pliku, a nie skrót), ale wciąż dziękuję. Naprawdę pomocny. Mogę powiedzieć, że lubisz jedynki. : D
rbaleksandar
1

Korzystając z tej odpowiedzi , otrzymałem życzenie:

for %%f in (*.json) do (
    echo %%f
    setlocal enabledelayedexpansion
    set /a count=1 
    for /f "skip=1 delims=:" %%a in ('CertUtil -hashfile "%%f" SHA256') do (
      if !count! equ 1 (
        echo %%a >> HASH.txt
      )
      set/a count+=1
    )
    endlocal
)

Skrypt wyświetla plik HASH.txtz zawartością:

227041a0fb9086c047692b5fc5e96437abe7a2664cc7e2dbcaa0bbe9c89cd886 bf4cf9401299ee68d24c88d1ff93152d4333956c58b305144b6469d86a8a803f 7b64b046d6121d9ef7db9e8f4a46b11b583a2c294501cf805120982d1a3b4b4c b5ff9fcd040d55ba77a75578d8bee5d26382d3ba952c38952fefcbe08cc10b9f a78294c3e0d7e6311ada02da35ea25240edc7b0f7c2e601e9840162e5fb5228c f3b21270b95d514e24a68658c77718cbe827487cdc32b46864a67172ae0afebc 0affcf4c3ba645c7aff44cfcb08fabd8769e84042b935907199d031601bf8e6a 3c197b9b991c6e9d66db0fee74d2fe2ea332e7f649459b08d89ba34e89ae9d27 5d676c597f4839bf05feace8d02fa1ec6e4c08d8b5f75266c0237cdd816f838b 323fc8da682b19aa11c250dd5129c7a581572e82ad88fb9c52f8c0679d7b8c12 49ec95e5b45c74638e035a37983de74da91d4aea78d35abe749ce9d5556c1c5d 84f1b5865d7949127bcc4a64e664ea75422cf4364c3e4acc2989e991cd6d0056588f1173ac020b589a632d2d6dba61958243d78efe10afd2bb21cc49a33a146a 6a9e8887d25f5719568bf5321845d90afc800457947c3522f76717e469e3acea 2d4800aa9c58c477f4bfeab47a98bc35aab8446a53453a43ed40a553066549c9 f5e307075774bfa0eb9b65891c428799658d36e1b42be28cba67a920069a2c21 ad755392444209412dc49d172603c4f7fa693589a0390ae626470f96d8ebb22b 8ac329790c5df762bfb5d3437b2470fcd238b426ad60541ae89394f2620d867c cb6e4239db4cf53e236dcea70c245f053b636b70830d3f80946433f702049b95 0403ab147b4d4788ce84df45c52c33e004cbdf9c77ad14a7b844e56b18bf9d00 b9459119c08710713f5fb5816446149bf1314b34aa359c7ef35c12c1bf40ef27 235bd76cf4c4684714ec42847a1bd0a673eb07f5ee19c9bc86ce6f1a9d24449e 082cb0bee5ef63ec6c6ed5307000af5c89af2e75c6f9abdad9d3fafe37a725bf 3af4b54bd63686df3175cf9e2d4f24bb4600385230b86f8342efa9a039f31c3c96ca349e805dae74aabb8252d2c4ffdabe17cabe0421742e1d12e672070f06b5 d8338f6f2649bcb358e56e0973fe2f5a886771e0debbdb0fefef35976a1b88ca

Zasadniczo wyjście z certUtiltraktowany jest jak zawartość pliku tekstowego, pozwalającego na wykorzystywanie skip, delimetc.

rbaleksandar
źródło
Możesz ułatwić sobie życie, filtrując dane wyjściowe certutil za pomocą findstr /V ":"skrótu, który jest jedyną linią bez dwukropka. Możesz więc zamienić całe wnętrze naCertUtil -hashfile "%%f" SHA256 | findstr /V ":" >> HASH.txt
LotPings
Czy możesz to opublikować jako odpowiedź? Jest znacznie krótszy i elegancki niż to, co obecnie mam. : D
rbaleksandar
1

Aby przyspieszyć, użyj filtra zamiast zapętlania:

@echo off
setlocal EnableDelayedExpansion
if exist hash.txt del hash.txt

for %%f in (*.json) do (
   for /f "delims=" %%_ in ('certutil -hashfile %%f SHA256 ^| find /v ":"') do (
      set x=%%_
      set x=!x: =!
   )
   echo !x! >> hash.txt
)

Druga linia w najbardziej wewnętrznym bloku (druga fornie jest pętlą!) Odrzuca puste wartości wartości skrótu.
endlocaljest niejawny z końcem pliku wsadowego.

użytkownik1016274
źródło
0

Jeśli mogę odpowiedzieć poleceniem unix (Microsoft ogłosi, że osadzi cały program narzędziowy unix w aktualizacji systemu Windows 10 i nowej wersji):

  • sed -n "3p" "C: \ Temp \ my_file.txt" (wiersz wyjściowy 3 pliku lub StdIn)

W przeciwnym razie dość łatwo jest „skopiować / wkleić” stary, uniksowy, wiarygodny program kompilacyjny dla systemu Windows, aby wykonać zadanie dość łatwo:

Przed tą aktualizacją systemu Windows 10 możesz użyć:

  • wpisz „C: \ Temp \ my_file.txt” | findstr / n. | findstr / b ^ 3: (spowoduje to wyświetlenie wiersza 3 pliku, ale numer wiersza będzie musiał zostać usunięty)
Martin Desaulniers
źródło