Apa cara terbaik untuk melakukan substring dalam file batch?

192

Saya ingin mendapatkan nama file batch yang sedang berjalan tanpa ekstensi file.

Berkat tautan ini , saya memiliki nama file dengan ekstensi ... tapi apa cara terbaik untuk melakukan substring dalam file batch?

Atau ada cara lain untuk mendapatkan nama file tanpa ekstensi?

Aman untuk mengasumsikan ekstensi 3 huruf dalam skenario ini.

JosephStyons
sumber

Jawaban:

398

Nah, untuk hanya mendapatkan nama file batch Anda, cara termudah adalah dengan menggunakannya %~n0.

@echo %~n0

akan menampilkan nama (tanpa ekstensi) dari file batch yang sedang berjalan (kecuali dijalankan dalam subrutin yang dipanggil oleh call). Daftar lengkap pergantian "khusus" untuk nama jalur seperti itu dapat ditemukan help for, di bagian paling akhir bantuan:

Selain itu, substitusi referensi variabel FOR telah ditingkatkan. Anda sekarang dapat menggunakan sintaks opsional berikut:

%~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

Pengubah dapat digabungkan untuk mendapatkan hasil majemuk:

%~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

Untuk menjawab pertanyaan Anda dengan tepat, namun: Substring dilakukan menggunakan :~start,lengthnotasi:

%var:~10,5%

akan mengekstraksi 5 karakter dari posisi 10 dalam variabel lingkungan %var%.

CATATAN: Indeks string berdasarkan nol, sehingga karakter pertama berada di posisi 0, yang kedua di 1, dll.

Untuk mendapatkan substring dari variabel argumen seperti %0, %1, dll Anda harus menetapkan mereka untuk variabel lingkungan yang normal menggunakan setpertama:

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

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

Sintaksnya bahkan lebih kuat:

  • %var:~-7% ekstrak 7 karakter terakhir dari %var%
  • %var:~0,-4%akan mengekstrak semua karakter kecuali empat yang terakhir yang juga akan menghilangkan Anda dari ekstensi file (dengan asumsi tiga karakter setelah periode [ .]).

Lihat help setdetail tentang sintaks itu.

Joey
sumber
31
Ekstraksi substring tidak bekerja dengan variabel FOR loop jadi Anda harus melakukan sebagai berikut (\ r \ n dalam kode berarti jeda baris karena SO sepertinya tidak mengizinkan jeda baris dalam komentar):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT
@ Fr0sT mengapa Anda harus melakukan ini untuk FORloop?
Bob
4
@Adrian kenapa tidak? FORadalah konstruksi landasan dalam file batch melakukan sejumlah besar tugas yang cukup besar. Btw, ada satu cara lagi untuk mengatasi tugas dengan menggunakan subrutin, yaitufor /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
menggunakan windows server 12 R2,% date% tampak seperti 21/05/18 (budaya IT); string yang tepat adalah: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01
@ Phate01, jangan gunakan %date%untuk membuat tanggal dalam format tertentu. Formatnya khusus untuk budaya pengguna dan dapat berubah. Gunakan WMI sebagai gantinya untuk mendapatkan tanggal dan waktu dalam format yang bermanfaat yang tidak bergantung pada pengaturan pengguna. Saya juga tidak yakin apa yang dilakukan komentar ini di sini, karena pertanyaan ini bukan tentang tanggal atau waktu.
Joey
38

Dijelaskan dengan baik di atas!

Untuk semua orang yang mungkin menderita seperti saya agar ini berfungsi di Windows yang dilokalkan (milik saya adalah XP dalam bahasa Slowakia), Anda dapat mencoba untuk mengganti %dengan!

Begitu:

SET TEXT=Hello World
SET SUBSTRING=!TEXT:~3,5!
ECHO !SUBSTRING!
BrandonSk
sumber
27
Perhatikan ini hanya akan berfungsi setelah setlocal ENABLEDELAYEDEXPANSIONperintah
Fr0sT
13

Sebagai info tambahan untuk jawaban Joey, yang tidak dijelaskan dalam bantuan set /?juga for /?.

%~0memperluas nama batch sendiri, persis seperti yang diketik.
Jadi, jika Anda memulai batch Anda, itu akan diperluas sebagai

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

Tapi ada satu pengecualian, ekspansi dalam subrutin bisa gagal

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

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

Ini menghasilkan

main - myBatch
Func - :myFunction
func - mybatch

Dalam suatu fungsi %~0mengembang selalu ke nama fungsi, bukan dari file batch.
Tetapi jika Anda menggunakan setidaknya satu pengubah itu akan menampilkan nama file lagi!

jeb
sumber