Wsad: Usuń rozszerzenie pliku

155

Mam następujący skrypt wsadowy z Wikipedii:

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%f
)
pause

W pętli for wszystkie pliki z rozszerzeniem flv są powtarzane, ale chcę, aby wykonać pewne działania z plikiem (plikami), w których potrzebuję raz pliku bez rozszerzenia i raz z rozszerzeniem. Jak mogłem dostać te dwa?

Szukałem rozwiązań, ale nie znalazłem. Jestem prawdziwym nowicjuszem w partii ...

Poru
źródło

Odpowiedzi:

309

Możesz użyć, %%~nfaby uzyskać nazwę pliku tylko zgodnie z opisem w dokumentacji dla for:

@echo off
    for /R "C:\Users\Admin\Ordner" %%f in (*.flv) do (
    echo %%~nf
)
pause

Dostępne są następujące opcje:

Zmienna z modyfikatorem Opis

% ~ I ​​Rozwija% I, co usuwa otoczenie 
                        cudzysłów ("").
% ~ fI Rozwija% I do pełnej nazwy ścieżki.
% ~ dI Rozwija% I tylko do litery dysku.
% ~ pI Rozwija% I tylko do ścieżki.
% ~ nI Rozwija% I tylko do nazwy pliku.
% ~ xI Rozwija% I tylko do rozszerzenia pliku.
% ~ sI Rozwija ścieżkę, aby zawierała tylko krótkie nazwy.
% ~ aI Rozwija% I do atrybutów pliku file.
% ~ tI Rozszerza% I do daty i godziny pliku.
% ~ zI Rozszerza% I do rozmiaru pliku.
% ~ $ PATH: I Przeszukuje katalogi wymienione w środowisku PATH 
                        zmiennej i rozwija% I do w pełni kwalifikowanej nazwy 
                        pierwszy znaleziony. Jeśli nazwa zmiennej środowiskowej to
                        nie zdefiniowano lub plik nie został znaleziony przez wyszukiwanie,
                        ten modyfikator rozwija się do pustego ciągu.    
Dirk Vollmar
źródło
8
Krótka uwaga: w powyższym przykładzie %% f byłoby czymś podobnym, C:\Users\Admin\Ordner\foo.flva %% ~ nf dałoby ci foo. Jeśli chcesz wszystko oprócz rozszerzenia, użyj %% ~ df %% ~ pf %% ~ nf, co by ci dałoC:\Users\Admin\Ordner\foo
ehambright
8
@ehambright Późny komentarz, ale myślę, że użycie %%~dpnfbyłoby krótszą alternatywą.
Dzięki za modyfikator / tabelę opisów Dirk. W moim przypadku nazwa pliku bez rozszerzenia pochodziła z parametru param %1w skrypcie wsadowym. echo %~n1było to, czego szukałem.
Dave Pile
26

W przypadku, gdy plik, który zawiera zmienna, w rzeczywistości nie istnieje, FORpodejście nie zadziała. Jedną sztuczką, której możesz użyć, jeśli znasz długość rozszerzenia, jest pobranie podciągu:

%var:~0,-4%

to -4oznacza, że ostatnie 4 cyfry (przypuszczalnie .ext ) zostaną obcięte.

Ohad Schneider
źródło
To nie działa dla mnie (na Win8.1) - być może źle to zrozumiałem, próbując echo %f:~0,-4%w kontekście przykładu użytego w pytaniu. Co ja robię źle?
Wolf
2
Najwyraźniej działa to dla „normalnych” zmiennych, a nie dla zmiennych FOR (a może po prostu nie znam poprawnej składni). W każdym razie zadziała to w kontekście przykładu OP: SET fl=%%fa następnieecho %fl:~0,-4%
Ohad Schneider
@Wolf musisz ustawić wartość zmiennej pętli na normalną zmienną, a następnie wykonać podstawienie / obcięcie ciągu w normalnej zmiennej
phuclv
W wielu przypadkach długość przedłużenia nie jest równa 3 lub jest nieznana. Nadal możesz użyć for, nawet jeśli plik nie istnieje, zobacz moją odpowiedź.
marsze
14

Nie znam też Windows cmd, ale spróbuj tego:

echo %%~nf
Vineet
źródło
8

To jest naprawdę późna odpowiedź, ale wymyśliłem to, aby rozwiązać konkretny problem, który miałem z DiskInternals LinuxReader dołączającym `` .efs_ntfs '' do plików, które zapisał w katalogach innych niż NTFS (FAT32):

@echo off
REM %1 is the directory to recurse through and %2 is the file extension to remove
for /R "%1" %%f in (*.%2) do (
    REM Path (sans drive) is given by %%~pf ; drive is given by %%~df
    REM file name (sans ext) is given by %%~nf ; to 'rename' files, move them
    copy "%%~df%%~pf%%~nf.%2" "%%~df%%~pf%%~nf"
    echo "%%~df%%~pf%%~nf.%2" copied to "%%~df%%~pf%%~nf"
echo.
)
pause
Agi Hammerthief
źródło
Nie jestem pewien, czy odpowiada na zadane pytanie, ale tak naprawdę pomogło mi, dzięki!
matan7890
1
@ matan7890 True; op nie określa, co pociąga za sobą „Chcę, aby wykonać pewne działania z plikiem (plikami)” [sic], ale jedną z tych czynności może być zmiana ich nazw, w którym to przypadku moja odpowiedź jest rozszerzeniem zaakceptowanej odpowiedzi.
Agi Hammerthief
Pomogło to mojemu przyjacielowi, który otworzył załącznik i .encrypteddodał do wszystkich swoich plików wraz z żądaniem okupu. Najwyraźniej atakujący skrypt musiał być plikiem wsadowym, który jest odwrotnością tego i dodany .encrypteddo wszystkich plików.
AwokeKnowing
1
pozytywnie rozpatrzony, ponieważ podajesz dysk, ścieżkę i rozszerzenie ( %% ~ df %% ~ pf %% ~ nf ), które najbardziej przypomina wynik %% f z oryginalnego pytania, zamiast tylko nazwy pliku bez rozszerzenia ( %% ~ nf )
ehambright
5

Używam tego, jeśli chcę po prostu usunąć rozszerzenie ze zmiennej (bez zapętlania żadnych katalogów lub istniejących plików):

for %%f in ("%filename%") do set filename=%%~nf

Jeśli chcesz usunąć rozszerzenie z pełnej ścieżki, użyj %%dpnfzamiast tego:

for %%f in ("%path%") do set path=%%~dpnf

Przykład:

(Użyj bezpośrednio w konsoli)

@for %f in ("file name.dat") do @echo %~nf
@for %f in ("C:\Dir\file.dat") do @echo %~dpnf

OUTPUT:

file name
C:\Dir\file
marsze
źródło
0

Używanie cygwin bash do robienia siekania

  :: e.g. FILE=basename.mp4 => FILE_NO_EXT=basename
  set FILE=%1
  for /f "delims=" %%a in ('bash -c "FILE=%FILE%; echo ${FILE/.*/}" ') do set FILE_NO_EXT=%%a
mosh
źródło
0

Jeśli zmienna jest argumentem, możesz po prostu użyć, %~dpnpo której następuje numer argumentu, więc nie musisz się martwić o różne długości rozszerzeń.

Na przykład %~dpn0zwróci ścieżkę do pliku wsadowego bez rozszerzenia, %~dpn1będzie %1bez rozszerzenia itp.

Martin Braun
źródło