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.