CMD: *. * O solo *?


47

Negli anni '90, avrei usato " *.*" per rappresentare qualsiasi nome di file in MS-DOS, ma in *questi giorni ho visto più script usando solo " ". Fa davvero la differenza quale utilizzo?


9
Mentre è vero che *e *.*sono ora equivalenti per cmdi comandi interni e le moderne utility della riga di comando, alcune utility più vecchie che accettano parametri di maschere di file possono usare le funzioni di corrispondenza dei file più vecchie e per loro le maschere non saranno equivalenti.
AFH,

@AFH Non penso che i token siano uguali. Il *.*token non dovrebbe restituire file senza estensione.
tuskiomi,

1
@tuskiomi - Sono d'accordo con te che *.* non dovrei restituire file senza estensione. Purtroppo lo fa. Vedi la risposta di Grawity.
AFH,

Risposte:


65

Il nome e l'estensione del file sono stati un singolo campo sin da quando Windows 95 e NT 3.5 hanno introdotto il supporto per "nome file lungo" e le corrispondenze con caratteri jolly vengono eseguite contemporaneamente sull'intero nome file. Di conseguenza, puoi avere un nome file senza punti (forse raro per i file, ma molto comune per cartelle / directory) e a prima vista in *.*realtà non corrisponderebbe a tali file.

I vecchi script che usano *.* funzioneranno comunque a causa del codice di compatibilità - se il carattere jolly termina con .*, quella parte viene ignorata dal sistema operativo. (Quindi, se si desidera abbinare in modo specifico i file con un'estensione, suppongo che ne avresti bisogno *.?*.)

Ma non è qualcosa su cui dovresti fare affidamento; se stai scrivendo script per le moderne versioni di Windows, segui le loro convenzioni, non quelle di MS-DOS. (Si noti che a partire da Windows NT, gli script .bat non vengono più interpretati da MS-DOS ma da cmd.exeun programma nativo Win32.)


Su Linux e vari altri Unixen, il nome e l'estensione non sono mai stati separati in primo luogo, e non c'è alcuna magia speciale per far *.*funzionare, quindi *è l'unica scelta che abbia senso.


14
"Rendiamo più difficile filtrare i file con estensioni! Yay!" -Anonimo sviluppatore Microsoft
John Hamilton,

50
"Rompiamo i milioni di script batch esistenti per tutti! Yay!" -Nessun sviluppatore Microsoft, mai
grawity

3
ISTR che su alcune vecchie versioni di DOS *corrisponderebbe solo ai nomi di file senza estensione. Il modo "sicuro" di essere compatibile con entrambi era di usare **.
Casuale 832,

8
L'OP riguarda Windows, ma dato che hai menzionato Linux: in alcune shell (Bash, per esempio), *( per impostazione predefinita ) non corrisponde ai nomi di file nascosti (che iniziano con a .).
Florian Brucker,

4
Per alcuni valori di "livello del sistema operativo" ... È davvero un concetto di shell (Explorer) anche in Windows - al kernel non interessa l'exe sui file eseguibili, né altro. Si può sostenere se Windows Explorer sia più "a livello di sistema operativo" rispetto ad esempio a Nautilus in Linux.
Grawity,

11

E 'probabilmente la pena ricordare che l'Unixy / conchiglie posixy come Bourne shell, bash, ksh, zsh, ecc fanno espansione jolly (di caratteri glob piace *, ?, [range], [!range]e altre espansioni come bretelle e gocce estesi) per compilare un elenco di argomenti prima che il comando viene eseguito. Quindi questa espansione viene eseguita dalla shell e non dal comando di cui questi possono essere argomenti.

cioè la shell è responsabile di cosa *, si *.*espande a

 $ 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

Questo non è il caso di CMD (e in modo simile per le utility PowerShell ) in quanto passa i caratteri glob alla lettera al comando eseguito - e quindi l'espansione è la responsabilità del comando / utilità e non della shell. Quindi, in definitiva, cosa *.*o cosa *viene lasciato all'utilità lasciandola conforme (o meno) alle convenzioni - motivo per cui le utilità di CMD come dir *.*anche abbinato (probabilmente in modo errato ma conservando le aspettative) file senza estensioni.

Credo che sia sicuro riassumere in questo modo.

  • Sotto CMD dipende dall'utilità.
  • In PowerShell, i programmi di utilità che utilizzano la classe WildCardPattern forniranno un sottoinsieme coerente di comportamenti posixy.

Un'altra differenza è che in CMD, la maggior parte dei programmi inoltra effettivamente il jolly non elaborato al kernel (FindFirstFile), mentre glob su Linux prende semplicemente l'elenco completo e filtra nello spazio utente.
Grawity,

Quando si esegue * su una directory con un milione di file, il comando si lamenterà di troppi parametri. Nel peggiore dei casi, potrebbe far cadere silenziosamente la coda dell'elenco. In questi casi, è necessario reindirizzare due o più comandi o salvare un elenco di nomi di file in un file, in modo che altri processi possano leggere l'elenco.
Enric Naval,

3
@grawity Per essere più precisi, il filtro viene eseguito dal driver del file system su Windows. Ciò è particolarmente utile sui file system di rete (specialmente quando si potrebbe eseguire una linea da 8 kb su un file system remoto), ma significa anche che non è possibile effettuare ricerche arbitrarie o ricerche esplicitamente supportate. Le implicazioni di questo sono state esplorate molte volte sul blog di Raymond Chen. FindFirstFilestesso è in modalità utente (sia kernel32.dll che ntdll.dll sono librerie in modalità utente - fa parte del sottosistema Win32, non del kernel), ma non fa molto.
Luaan,

Ah, ho avuto l'impressione che FindFirstFile abbia praticamente avvolto direttamente un simile syscall (come il modo in cui open (3) in libc semplicemente avvolge open (2) nel kernel Linux).
Grawity il

1
@cup: basta usare le virgolette per impedire alla shell di espandere globs, in modo da poterle passare ai comandi. es mmv "fred.*" "tom.#1". (La sostituzione usa #1invece di *, il che ha il vantaggio di permetterti di riordinare i campi). mmvnon è installato di default sulla maggior parte dei sistemi, ma spesso lo sono altri strumenti per rinominare i lotti. Vedi questo articolo a riguardo e stackoverflow.com/questions/417916/how-to-do-a-mass-rename .
Peter Cordes,
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.