Qual è il modo migliore per eseguire una sottostringa in un file batch?


192

Voglio ottenere il nome del file batch attualmente in esecuzione senza l'estensione del file.

Grazie a questo link , ho il nome del file con l'estensione ... ma qual è il modo migliore per eseguire una sottostringa in un file batch?

O c'è un altro modo per ottenere il nome del file senza l'estensione?

È sicuro assumere estensioni di 3 lettere in questo scenario.

Risposte:


398

Bene, per ottenere solo il nome del file del tuo batch il modo più semplice sarebbe semplicemente usare %~n0.

@echo %~n0

produrrà il nome (senza estensione) del file batch attualmente in esecuzione (a meno che non venga eseguito in una subroutine chiamata da call). L'elenco completo di tali sostituzioni "speciali" per i nomi dei percorsi è disponibile help foralla fine dell'aiuto:

Inoltre, è stata migliorata la sostituzione dei riferimenti alle variabili FOR. Ora puoi usare la seguente sintassi opzionale:

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

I modificatori possono essere combinati per ottenere risultati composti:

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

Per rispondere con precisione alla tua domanda, tuttavia: i sottostringhi vengono eseguiti utilizzando la :~start,lengthnotazione:

%var:~10,5%

estrarrà 5 caratteri dalla posizione 10 nella variabile d'ambiente %var%.

NOTA: l'indice delle stringhe è basato su zero, quindi il primo carattere è nella posizione 0, il secondo in 1, ecc.

Per ottenere sottostringhe di variabili argomento come %0, %1ecc., Devi assegnarle a una normale variabile d'ambiente usando setprima:

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

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

La sintassi è ancora più potente:

  • %var:~-7% estrae gli ultimi 7 caratteri da %var%
  • %var:~0,-4%estrarrebbe tutti i caratteri tranne gli ultimi quattro che ti libererebbero anche dell'estensione del file (assumendo tre caratteri dopo il punto [ .]).

Vedere help setper i dettagli su quella sintassi.


31
L'estrazione di sottostringa non funziona con le variabili del ciclo FOR, quindi dovrai fare come segue (\ r \ n nel codice significa interruzioni di riga perché SO sembra non consentire interruzioni di riga nei commenti):setlocal ENABLEDELAYEDEXPANSION \r\n for /f %%s in ('set') do ( \r\n set tmp=%%s \r\n echo !tmp:~-3! \r\n )
Fr0sT

@ Fr0sT perché devi farlo per i FORloop?
Bob,

4
@Adrian perché no? FORè una costruzione fondamentale in file batch che esegue un numero piuttosto elevato di vari compiti. A proposito, c'è un altro modo per far fronte all'attività usando una subroutine, cioèfor /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
usando Windows Server 12 R2,% date% è simile al 21/05/18 (cultura IT); la stringa giusta è: %date:~0,2%%date:~3,2%%date:~6,4%%time:~0,2%%time:~3,2%%time:~6,2%
Phate01

@ Phate01, non usare %date%per costruire una data in un determinato formato. Il formato è specifico per la cultura dell'utente e potrebbe cambiare. Utilizzare invece WMI per ottenere la data e l'ora in un formato utile che non dipende dalle impostazioni dell'utente. Inoltre, non sono sicuro di cosa stia facendo questo commento, poiché questa domanda non riguardava la data o l'ora.
Joey,

38

Ben spiegato sopra!

Per tutti coloro che potrebbero soffrire come me per farlo funzionare in un Windows localizzato (il mio è XP in slovacco), potresti provare a sostituire il %con un!

Così:

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

27
Nota che funzionerà solo dopo il setlocal ENABLEDELAYEDEXPANSIONcomando
Fr0sT

13

Come informazioni aggiuntive alla risposta di Joey, che non è descritta nella guida di set /?for /?.

%~0si espande nel nome del proprio batch, esattamente come è stato digitato.
Quindi se avvii il tuo batch verrà espanso come

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

Ma c'è un'eccezione, l'espansione in una subroutine potrebbe non riuscire

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

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

Questo risulta a

main - myBatch
Func - :myFunction
func - mybatch

In una funzione si %~0espande sempre al nome della funzione, non del file batch.
Ma se usi almeno un modificatore mostrerà di nuovo il nome del file!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.