Toplu iş komut dosyasında 'find' komutuyla dosyaya yazma


5

Aşağıdakileri yapan pencereler için bir toplu komut dosyasına ihtiyacım var:

  1. tüm dosya isimlerini bir dizinden bir .txt dosyasına döker (genellikle birkaç yüz ila 50 bine yakın dosya)
  2. çıktı dosyasını belirli dizeler için arar (bunlardan yaklaşık 35'i), sayar ve sonuçlarıyla başka bir dosya oluşturur

Bugünden önce hiçbir şeyi senaryo yazmadığım için şunu yazdım:

@echo off  
dir /b > maps.txt  
(  
find /c /i "string1" maps.txt  
find /c /i "string2" maps.txt  
...  
find /c /i "string35" maps.txt  
)  > results.txt  

Sonuç umut verici, ancak sonuç dosyası şöyle görünecek şekilde sayım ile birlikte results.txt dosyasında numaralandırılmış dizgelere ihtiyacım olacak:

string1 = 3  
string2 = 5  
...  
string35 = 1 

Bir .csv dosyası da olur, bu durumda aşağıdaki biçime ihtiyacım olur:

string1;3  
string2;5  
...  
string35;1  

Böyle bir şey mümkün mü?


Bol miktarda bilgi verdiniz, bu yüzden ilk sorunuz için endişelenmenize gerek yok (IMO). Genellikle sadece "X'i içeren bir komut dosyasına ihtiyacım var." bunlar daha sonra kapalı. Sana bir şey denediğini göstermek için +1! :)
Ƭᴇcʜιᴇ007

"SORT" komutu yardımcı olabilir. Önerdiğiniz biçim .csv ("virgülle ayrılmış değer") değil, .ssv ("yarı-kolon" - ayrılmış değer) gibi görünüyor.
TOOGAM

"SORT" bana yardımcı olmaz - daha doğrusu - daha sonra yardımcı olabilir. Şimdi aradığım şey, dizeyi sayıya 'bağlamak', şu anda olduğu gibi, results.txt dosyası şöyle görünüyor: ------ MAPS.TXT: 1 Ve "---------- MAPS.TXT" örneklerini o zaman sayılan gerçek dizelerle değiştirmem gerekir. 'Find' komutu 'echo' ile farklı bir şekilde birleştirilebilir mi? Ya da belki farklı bir sayma yöntemine ihtiyacım var?
Mateusz Watman Wata

Yanıtlar:


2

Dize Başına Toplam Dize Sayısı

Toplu Komut Dosyası (örtülü)

@ECHO OFF

::: If this file exists, delete it 
IF EXIST "Results.txt" DEL /Q /F "Results.txt"

::: Bare format DIR command listing ONLY filename.extension 
DIR /B > maps.txt

::: Please go to command line and type FOR /? and look through there for the FOR /F explanations
::: This is saying for each line in strings.txt do a FIND /I for each string in maps.txt and if FIND /I finds a string, then CALL the StringCountRoutine and pass the string found as the first argument to the CALL :label (:StringCountRoutine in this instance)
::: Please note that is a string IS NOT FOUND then there will be no count and not a zero unfortunately so it's implied that is the string is not in the results.txt file, then the count of that string is zero
FOR /F "TOKENS=*" %%S IN (Strings.txt) DO (FIND /I "%%S" maps.txt && CALL :StringCountRoutine "%%~S")
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

:StringCountRoutine
::: This is saying the TOKEN count is three and each token to count (the DELIMITER) are colons and spaces ("DELIMS=: ") so for example this (---------- MAPS.TXT: 14) has two spaces and one colon so only have the variable be what's left afterwards which is just the number when set this way
::: The first argument is passed to the FIND /C command as listed below and also the ECHO command afterwards
FOR /F "TOKENS=3DELIMS=: " %%A IN ('FIND /C "%~1" maps.txt') DO (ECHO %~1 = %%A >> Results.txt)
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

Dosyadaki Dizeleri Ara ve Başka Dosyadaki Aynı Dizeleri Bul

Aşağıda, ihtiyacım olanı yapmanın bir yolunu gösteren iki örnek verilmiştir; string Her bir dizgenin o dosyadaki satır başına temsil edildiği ayrı bir metin dosyasına verilen değerler. Bu kadar TOKENS=* içinde FOR /F Satır, her satırı satır olarak veya boşluk olmadan okuyacak string aradığınız değer map.txt dosya.

Örtükçe Tanımlanmış Komut Dosyası

@ECHO OFF

::: If this file exists, delete it 
IF EXIST "Results.txt" DEL /Q /F "Results.txt"

::: Bare format DIR command listing ONLY filename.extension 
DIR /B > maps.txt

::: Set seq variable to 1 for the first sequence number
SET seq=1

::: Please go to command line and type FOR /? and look through there for the FOR /F explanations
::: This is saying for each line in strings.txt do a FIND /I for each string in maps.txt and if FIND /I finds a string, then CALL the SeqAdditionRoutine and pass the string found as the first argument to the CALL :label (:SeqAdditionRoutine in this instance)
FOR /F "TOKENS=*" %%S IN (Strings.txt) DO (FIND /I "%%S" maps.txt && CALL :SeqAdditionRoutine "%%~S")
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

:SeqAdditionRoutine
::: This is saying FIND /I but with first argument passed as the string (same as above FIND /I but the first argument is passed here), and if successful (the double AND) ECHO the string equals 1 (or the sequence number variable value) to results.txt
FIND /I "%~1" maps.txt && ECHO %~1 = %seq% >> results.txt
::: This is saying (see SET /?) whatever seq variable is set to, ADD one to it and set it to this new value for whatever adding one to it will make it when it goes to EOF, it'll loop the next command (the CALLing loop) with this new value until it is successful in finding a strings and comes back down here again
SET /A seq=%seq%+1
::: GOTO EOF needed here to pass control back to the CALLER or END once loop is complete to it doesn't move on to logic beneath which should only be called
GOTO EOF

Açıkça Tanımlanmış Komut Dosyası

@ECHO OFF

SET stringlist=C:\folder\folder\Strings.txt
SET mapsfile=C:\folder\folder\Maps.txt
SET resultsfile=C:\folder\folder\Results.txt

IF EXIST "%resultsfile%" DEL /Q /F "%resultsfile%"

DIR /B > "%mapsfile%"

SET seq=1
FOR /F "TOKENS=*" %%S IN (%stringlist%) DO (FIND /I "%%S" "%mapsfile%" && CALL :SeqAdditionRoutine "%%~S")
GOTO EOF

:SeqAdditionRoutine
FIND /I "%~1" "%mapsfile%" && ECHO %~1 = %seq% >> "%resultsfile%"
SET /A seq=%seq%+1
GOTO EOF

Güncelleştirme

Bunu örtük komut dosyasından test ettim ve beklendiği gibi çalıştı. . .

Ben sadece string = number sadece içinde eşleşen bulduğu dizeler için Strings.txt ve hiçbiri maps.txt veya aynı dizindeki diğer txt dosyaları.

İçinde tanımladığım dizeler Strings.txt dosya sayılarla içerdi FIND /V Bunu farkettim string1 ayrıca eşleşti string10 ve string11 Benim örneğimdeki gibi. Bunun senin için bir sorun olup olmadığından emin değilim. values arama dizesi değer ölçütlerinizle eşleşecek, ancak bu, uyguladığınızda dikkate alınması gereken bir şey olabilir. Emin değilim eğer FINDSTR /L veya FINDSTR /I /C:"%~1" daha iyi ya da değil olurdu.


Yardımın için teşekkürler, ama bu bana ihtiyacım olan çıktıyı vermiyor (betiğin Implicit sürümünde herhangi bir şeyi değiştirmem gerekmiyorsa). Masaüstümde Strings.txt dosyasında 8 .txt dosyaları ve .txt dizesiyle çalışan test bana ".txt = 1" sonucunu verdi :( Böylece, gerçek dizelerin listesi işe yarıyor gibi görünüyor, ancak bunları saymıyor asıl bahsettiğim gibi, senaryo yazarken yeniyim, bu yüzden her ikisini de nasıl birleştireceğimi bilmiyorum - daha fazla yardım için minnettar olurum (ve bunun yerine bir rehber olsaydı, gerçek senaryo değil, böylece öğrenebilirdim) biraz ya da en azından ne olduğunu anlayın).
Mateusz Watman Wata

Tekrar teşekkürler, bu hala ihtiyacım olan şey değil, ne yazık ki. Benim için yazdığınız komut dosyası, strings.txt dosyasındaki dizelerin maps.txt dosyasında olup olmadığını kontrol eder ve eğer evet ise, belirli bir sayı verirse, maps.txt içindeki her bir dizinin oluşumunu saymam gerekirken yapar, ancak sonuçları şöyle ekolar: ---------- MAPS.TXT: 8 ---------- MAPS.TXT: 16 ---------- MAPS .TXT: 0 ---------- MAPS.TXT: 10 vs. (8 string 1, 16 string 2, 10 string 0, 10 string 4). (Bir sonraki yorumda TBC)
Mateusz Watman Wata

(DEVAMI) Sonuç olarak yankılanmanın bir yolu var mı: string1: 8 string2: 16 string3: 0 string4: 10 vs. FOR ve jetonlarla gitmek yerine ECHO komutuyla çalışmam gerekir mi? Ya da belki bunları farklı bir şekilde birleştirmem gerekiyor? misiniz find /c /i "string1" maps.txt && ECHO string1 = ? >> results.txt "?" yerine bir şey eklersem işe yarar ?
Mateusz Watman Wata

@MateuszWatmanWata görmek TOTAL STRING COUNT PER STRING bunun yerine, onu yeniden biçimlendirdim, bu yüzden kesin cevap en üstte, geri kalanlar da sizin ve diğerlerinin ihtiyaç duyduğu bonus. İyi şanslar!!
Pimp Juice IT

Teşekkür ederim! Son güncelleme beklendiği gibi çalışıyor ve tam ihtiyacım olan şey! Kudos sana!
Mateusz Watman Wata
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.