CMD: *. * Lub po prostu *?

47

W latach 90. używałbym „ *.*” do reprezentowania dowolnej nazwy pliku w MS-DOS, ale widziałem więcej skryptów używających teraz „ *”. Czy to rzeczywiście robi różnicę, którego używam?

Foebane
źródło
9
Chociaż prawdą jest, że *i *.*obecnie odpowiednik dla cmdpoleceń wewnętrznych i nowoczesnych narzędzi wiersza polecenia, niektórych starszych narzędzi, które mają parametry masce plików można używać starszych funkcji dopasowywania plików, a dla nich maski nie będą równoważne.
AFH
@AFH Nie sądzę, że tokeny są równe. *.*Żeton nie powinien wrócić pliki bez rozszerzeń.
tuskiomi,
1
@tuskiomi - Zgadzam się z tobą, że *.* nie powinny zwracać plików bez rozszerzeń. Niestety tak jest. Zobacz odpowiedź Grawity.
AFH,

Odpowiedzi:

65

Nazwa pliku i rozszerzenie są jednym polem , odkąd systemy Windows 95 i NT 3.5 wprowadziły obsługę „długich nazw plików”, a dopasowanie symboli wieloznacznych odbywa się jednocześnie dla całej nazwy pliku. W rezultacie możesz mieć nazwę pliku bez kropek (być może rzadką w przypadku plików, ale bardzo powszechną w przypadku folderów / katalogów) i na pierwszy rzut oka *.*nie pasuje do takich plików.

Stare skrypty używające nadal *.* będą działać z powodu kodu zgodności - jeśli symbol wieloznaczny kończy się na .*, część ta jest ignorowana przez system operacyjny. (Więc jeśli chcesz specjalnie dopasować pliki z rozszerzeniem, to chyba byś tego potrzebował *.?*.)

Ale na tym nie powinieneś polegać; jeśli piszesz skrypty dla nowoczesnych wersji systemu Windows, postępuj zgodnie z ich konwencjami, a nie konwencjami MS-DOS. (Należy pamiętać, że od Windows NT skrypty .bat niejuż interpretowane przez MS-DOS, ale przez cmd.exenatywny program Win32.)


W Linuksie i różnych innych systemach Unixen nazwa i rozszerzenie nigdy nie były oddzielne i nie ma żadnej specjalnej magii, aby *.*zadziałać, więc *jest to jedyny wybór, który ma sens.

grawitacja
źródło
14
„Utrudnijmy filtrowanie plików z rozszerzeniami! Tak!” -Anonimowy programista Microsoft
John Hamilton
50
„Przełammy miliony istniejących skryptów wsadowych dla wszystkich! Tak!” -Brak Microsoft Developer, Ever
grawity
3
ISTR, który w niektórych starych wersjach DOS pasowałby *tylko do nazw plików bez rozszerzenia. „Bezpiecznym” sposobem na kompatybilność z oboma było użycie **.
Random832
8
OP dotyczy systemu Windows, ale ponieważ wspomniałeś o Linuksie: W niektórych powłokach (na przykład Bash), *( domyślnie ) nie pasuje do ukrytych nazw plików (zaczynając od a .).
Florian Brucker
4
W przypadku niektórych wartości „poziomu systemu operacyjnego” ... To naprawdę jest koncepcja powłoki (Eksploratora) w systemie Windows - jądro nie dba o .exe w plikach wykonywalnych ani nic innego. Można argumentować, czy Eksplorator Windows jest bardziej „na poziomie systemu operacyjnego” niż np. Nautilus w Linuksie.
grawity
11

To chyba warto wspomnieć, że unixy / posixy muszle jak Bourne Shell, bash, ksh, zsh, etc zrobić wieloznaczny ekspansji (od znaków glob podoba *, ?, [range], [!range]i inne ekspansje jak szelki i rozszerzonych globs) sporządzić listę argumentów przed komendą jest wykonywany. Tak więc rozszerzenie jest wykonywane przez powłokę, a nie polecenie, dla którego mogą to być argumenty.

tj. Powłoka jest odpowiedzialna za co *, *.*rozwija się do

 $ ls
 file.csv  file.doc  file.pdf  file.txt  file.xlsx  zz-file-without-extension

 $ (set -xv; foo *)   # is actually expanded to the following
   + foo file.csv file.doc file.pdf file.txt file.xlsx zz-file-without-extension

 $ (set -xv; foo *.*)  # note this does not match `zz-file-without-extension`
   + foo file.csv file.doc file.pdf file.txt file.xlsx

Nie dzieje się tak w przypadku CMD (i podobnie w przypadku narzędzi PowerShell ), ponieważ przekazuje dosłownie znaki globalne do wykonanego polecenia - więc rozszerzenie jest odpowiedzialnością polecenia / narzędzia, a nie powłoki. Ostatecznie więc pozostaje to , co *.*lub co *pozostawia narzędziu, pozostawiając mu zgodność (lub nie) z konwencjami - dlatego narzędzia CMD lubią dir *.*także dopasowywać (prawdopodobnie niepoprawnie, ale zachowując oczekiwania) pliki bez rozszerzeń.

Uważam, że podsumowanie w ten sposób jest bezpieczne.

  • W CMD zależy to od narzędzia.
  • W programie PowerShell narzędzia korzystające z klasy WildCardPattern zapewnią spójny podzbiór posiksowych zachowań.
shalomb
źródło
Inna różnica polega na tym, że pod CMD większość programów faktycznie przekazuje surową kartę wieloznaczną do jądra (FindFirstFile), podczas gdy glob w Linuksie po prostu pobiera pełną listę i filtruje w przestrzeni użytkownika.
grawity
Gdy uruchomisz * w katalogu z milionem plików, polecenie narzeka na zbyt wiele parametrów. W najgorszym przypadku może po cichu upuścić ogon listy. W takich przypadkach musisz potokować dwa lub więcej poleceń lub zapisać listę nazw plików w pliku, aby inny proces mógł odczytać listę.
Enric Naval
3
@grawity Aby być bardziej dokładnym, filtrowanie odbywa się przez sterownik systemu plików w systemie Windows. Jest to szczególnie przydatne w sieciowych systemach plików (szczególnie w przeszłości, gdy można uruchomić linię o wielkości 8 kb do zdalnego systemu plików), ale oznacza to również, że nie można wykonywać dowolnych wyszukiwań, a także wyszukiwań jawnie obsługiwanych. Konsekwencje tego były wielokrotnie badane na blogu Raymonda Chena. FindFirstFilesam jest trybem użytkownika (zarówno kernel32.dll, jak i ntdll.dll są bibliotekami trybu użytkownika - to część podsystemu Win32, a nie jądro), ale tak naprawdę nie robi wiele.
Luaan
Ach, miałem wrażenie, że FindFirstFile prawie bezpośrednio zawinął podobnie nazwane syscall (na przykład jak open (3) w libc po prostu otacza open (2) w jądrze Linuksa).
grawity
1
@cup: Po prostu użyj cudzysłowów, aby zapobiec rozszerzaniu globusów przez powłokę, abyś mógł przekazać je komendom. np mmv "fred.*" "tom.#1". ( #1Zamiast tego używane są zamienniki *, co ma tę zaletę, że umożliwia zmianę kolejności pól). mmvnie jest instalowany domyślnie w większości systemów, ale często są dostępne inne narzędzia do zmiany nazw partii. Zobacz ten artykuł na ten temat i stackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Peter Cordes