Bir toplu iş dosyasında alt dize yapmanın en iyi yolu nedir?


192

Dosya uzantısı olmadan şu anda çalışan toplu iş dosyasının adını almak istiyorum .

Sayesinde bu bağlantı , ben dosya adına sahip olan uzantısı ... ama bir toplu iş dosyasında bir alt yapmanın en iyi yolu nedir?

Veya dosya adını uzantısı olmadan almanın başka bir yolu var mı?

Bu senaryoda 3 harfli uzantı kabul etmek güvenlidir.

Yanıtlar:


398

Sadece, toplu işinizin dosya adını almak için en kolay yol sadece kullanmak olacaktır %~n0.

@echo %~n0

çalışmakta olan toplu iş dosyasının adını (uzantısı olmadan) verir (tarafından çağrılan bir alt yordamda yürütülmedikçe call). Yol adları için bu tür "özel" ikamelerin tam listesini help foryardımın sonunda bulabilirsiniz:

Ek olarak, FOR değişken referanslarının ikamesi geliştirilmiştir. Artık aşağıdaki isteğe bağlı sözdizimini kullanabilirsiniz:

%~I         - expands %I removing any surrounding quotes (")
%~fI        - expands %I to a fully qualified path name
%~dI        - expands %I to a drive letter only
%~pI        - expands %I to a path only
%~nI        - expands %I to a file name only
%~xI        - expands %I to a file extension only
%~sI        - expanded path contains short names only
%~aI        - expands %I to file attributes of file
%~tI        - expands %I to date/time of file
%~zI        - expands %I to size of file
%~$PATH:I   - searches the directories listed in the PATH
               environment variable and expands %I to the
               fully qualified name of the first one found.
               If the environment variable name is not
               defined or the file is not found by the
               search, then this modifier expands to the
               empty string

Değiştiriciler, bileşik sonuçlar elde etmek için birleştirilebilir:

%~dpI       - expands %I to a drive letter and path only
%~nxI       - expands %I to a file name and extension only
%~fsI       - expands %I to a full path name with short names only

Ancak sorunuzu tam olarak cevaplamak için: Alt dizeler :~start,lengthnotasyon kullanılarak yapılır :

%var:~10,5%

ortam değişkenindeki 10. konumdan 5 karakter ayıklayacaktır %var%.

NOT: Dizelerin dizini sıfır tabanlıdır, bu nedenle ilk karakter 0 konumunda, ikincisi 1'de vb.

Gibi argüman değişkenlerinin alt dizeleri almak için %0, %1vb normal bir ortam değişkeni kullanarak bunları atamak zorunda setilk:

:: Does not work:
@echo %1:~10,5

:: Assign argument to local variable first:
set var=%1
@echo %var:~10,5%

Sözdizimi daha da güçlü:

  • %var:~-7% son 7 karakteri ayıklar %var%
  • %var:~0,-4%dosya uzantısından da sizi kurtaracak son dördü hariç tüm karakterleri alır (noktadan [ .] sonra üç karakter varsayarak ).

help setSöz dizimiyle ilgili ayrıntılar için bkz .


31
Alt dize ayıklama FOR döngü değişkenleri ile de çalışmaz, bu nedenle aşağıdaki gibi yapmanız gerekir (SO yorumlarda satır kesmelerine izin vermiyor gibi çünkü kod ortalama satır sonlarında \ r \ n):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT

@ Fr0sT Bunu neden FORdöngüler için yapmak zorundasınız ?
Bob

4
@ Adrian neden olmasın? FORtoplu iş dosyalarında çok sayıda çeşitli görevleri gerçekleştiren bir temel taşıdır. Btw, bir altyordam kullanarak görevle başa çıkmanın bir yolu daha var, yanifor /f %%s in ('set') do call :DoSmth "%%s" \r\n ... \r\n :DoSmth \r\n set var=%1 \r\n echo %var:~1,3%
Fr0sT

1
Windows Server 12 R2 kullanarak,% date% 21/05/18 (BT kültürü); doğru dize: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01

@ Phate01, %date%belirli bir biçimde tarih oluşturmak için kullanmayın . Biçim kullanıcının kültürüne özgüdür ve değişebilir. Tarih ve saati kullanıcının ayarlarına bağlı olmayan yararlı bir biçimde almak için WMI kullanın. Ayrıca bu sorunun burada ne yaptığından emin değilim, çünkü bu soru tarih veya saatle ilgili değildi.
Joey

38

Yukarıda güzel açıkladı!

Benim gibi ıstırap çeken herkes için bu çalışmayı yerelleştirilmiş bir Windows'da (benimki Slovakça XP'dir), yerine %bir!

Yani:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!

27
Bunun yalnızca setlocal ENABLEDELAYEDEXPANSIONkomuttan sonra çalışacağını unutmayın
Fr0sT

13

Joey'nin cevabına ek bir bilgi olarak, set /?ne de yardımında açıklanmadı for /?.

%~0tam olarak yazıldığı gibi kendi grubun adına genişler.
Bu nedenle, toplu işinize başlarsanız,

%~0   - mYbAtCh
%~n0  - mybatch
%~nx0 - mybatch.bat

Ancak bir istisna vardır, bir altyordamda genişlemek başarısız olabilir

echo main- %~0
call :myFunction
exit /b

:myFunction
echo func - %~0
echo func - %~n0
exit /b

Bu sonuç

main - myBatch
Func - :myFunction
func - mybatch

Bir işlevde %~0, toplu iş dosyası yerine her zaman işlevin adına genişletilir.
Ancak en az bir değiştirici kullanırsanız, dosya adını tekrar gösterecektir!

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.