Soru Toplu olarak virgülle ayrılmış dizeyle döngü nasıl?


, Windows

Gönderiye göre (dos batch ayrılmış bir dize boyunca yinelemek), Aşağıda bir senaryo yazdım ama beklendiği gibi çalışmıyor.

Hedef: "Güneş, Granit, Alacakaranlık" dizesi verildiğinde, her bir tema değerini döngü içinde almak istiyorum, böylece değerle bazı işlemler yapabilirim.

Akım çıkışı düzeltilemiyor:

list = "Sun,Granite,Twilight"
file name is "Sun Granite Twilight"

İlk iterasyon için şunlar olmalıdır:

list = "Sun,Granite,Twilight"
file name is "Sun"

Sonra ikinci yineleme "dosya adı" Granit "ve benzeri olmalıdır. Neyi yanlış yapıyorum?

Kod:

set themes=Sun,Granite,Twilight

call :parse "%themes%"
goto :end

:parse
setlocal
set list=%1
echo list = %list%
for /F "delims=," %%f in ("%list%") do (
    rem if the item exist
    if not "%%f" == "" call :getLineNumber %%f
    rem if next item exist
    if not "%%g" == "" call :parse "%%g"
)
endlocal

:getLineNumber
setlocal
echo file name is %1
set filename=%1
endlocal

:end

19
2018-06-18 00:01


Menşei




Cevaplar:


Kodunda birkaç değişiklik yaptım.

  1. Goto'ya ihtiyacınız var: altprogramların sonunda ve ana rutinin sonunda altprogramlara girmiyorsunuz.
  2. jetonlar = 1 * (%% f ilk jeton; %% g satırın geri kalanıdır)
  3. ~ set listesinde = tırnaklarını kaldırmak için% ~ 1 tırnaklar biriktirmez

    @echo off
    set themes=Sun,Granite,Twilight
    
    call :parse "%themes%"
    pause
    goto :eof
    
    :parse
    setlocal
    set list=%~1
    echo list = %list%
    for /F "tokens=1* delims=," %%f in ("%list%") do (
        rem if the item exist
        if not "%%f" == "" call :getLineNumber %%f
        rem if next item exist
        if not "%%g" == "" call :parse "%%g"
    )
    endlocal
    goto :eof
    
    :getLineNumber
    setlocal
    echo file name is %1
    set filename=%1
    goto :eof
    

6
2018-06-18 00:14



Bahşiş için teşekkürler! Çizgiyi açıklar mısınız: set list =% ~ 1% ~ 1 ne demektir? - masato-san
Sadece benim anlayışım için: şudur: “yerleşik” bir etiket? Bunu görmediğimden beri tanımlanmış. Ve alt programda "geri dönüş" olarak hareket eder? Garip kontrol akışı, yine de :) - Krischu
Belirli bir nedenden dolayı: getLineNumber %% f ile çağrılır ve: "%% g" ile ayrıştırılır (tırnak içinde)? - Krischu
Bunun dışında bir sebep yok, orijinal yazıdaki yol bu yüzden değiştirmedim. Eğer bunu sıfırdan yapıyor olsaydım, eğer bir dizge boşluklar, vb. Varsa, gelecekte sadece sorundan kaçınmak için %% f teklifini veririm. - RGuggisberg


Bunu yapmamın yolu budur:

@echo off
set themes=Sun,Granite,Twilight
echo list = "%themes%"
for %%a in ("%themes:,=" "%") do (
   echo file name is %%a
)

Yani, değişim Sun,Granite,Twilight tarafından "Sun" "Granite" "Twilight" ve sonra her bir parçayı tırnak içine alınmış düzenli bir şekilde işleme (NO / F seçeneği) for Komut. Bu yöntem yinelemeden çok daha basittir for /F döngü dayalı "delims=,".


37
2018-06-18 01:50



Tema adlarından birinin beyaz boşluk olduğunda da işleniyor mu? (Şu anda bu konuda sıkışıp kaldım ..) - masato-san
Virgüllerin yerine dize yerine ihtiyacın olduğunu düşünmüyorum. görmek: stackoverflow.com/a/8086103/82211 - Justin
@Justin: Evet, ancak bu durumda çözüm, "tema isminin biri beyaz boşluk olduğunda da işlenmez". - Aacini
Bu gerçekten temiz! Anlamak beni biraz aldı, ama temel olarak "for" komutu varsayılan olarak 1) sınırlayıcı olarak boşluk kullanmalı ve 2) tek tırnaklı öğeleri tek öğe olarak anlayacaktır. Bunun anlamı for %%a in ("one" "two" "three and four") do echo %%a çıktı verecek one\ntwo\three and four - rocketmonkeys


aldım AaciniCevabı kaldırmak ve sadece alıntılar kaldırmak için biraz değiştirildi, böylece tırnaklar istenen komutta olduğu gibi eklenebilir veya kaldırılabilir.

@echo off
set themes=Hot Sun,Hard Granite,Shimmering Bright Twilight
for %%a in ("%themes:,=" "%") do (
    echo %%~a
)

15
2018-04-05 17:10





"Jeton" anahtar kelimesine ihtiyacı var gibi görünüyor ...

@echo off
set themes=Sun,Granite,Twilight

call :parse "%themes%"
goto :end

:parse
setlocal
set list=%1

for /F "delims=, tokens=1*" %%f in (%list%) do (
    rem if the item exist
    if not "%%f" == "" call :getLineNumber %%f
    rem if next item exist
    if not "%%g" == "" call :parse "%%g"
)
endlocal
goto :end

:getLineNumber
setlocal
echo file name is %1
set filename=%1
endlocal 

:end

0
2018-06-18 00:30