web-dev-qa-db-fra.com

Existe-t-il un moyen d’obtenir du shell cmd Windows pour développer des chemins génériques?

De temps en temps, l'incapacité de la cmd Shell à développer des chemins génériques peut vraiment être un inconvénient. J'ai dû passer 100 fichiers dans un répertoire à un programme et je ne pouvais pas taper * .ext. Au lieu de cela, j'ai utilisé le 'ls' de mingw pour vider la liste dans un fichier, puis j'ai remplacé les nouvelles lignes par des espaces, copiées et collées dans cmd. C'est un cauchemar.

Je suppose que la réponse sera non, mais est-ce que quelqu'un a réglé le problème ou a trouvé un moyen de le rendre plus facile?

36
cemulate

DOS, et par conséquent le cmd.exe de Windows, n’a jamais supporté l’extension générique par le shell. C'était toujours à l'application de faire l'expansion.

Cela signifie que vous devrez toujours trouver un autre itinéraire si vous utilisez une application qui ne prend pas en charge l'expansion. Vous pourriez:

  • Utilisez une boucle FOR pour exécuter certaines commandes sur tous les fichiers qui vous intéressent
  • Utilisez dir /b > list.txt pour utiliser la commande dir afin de développer et de placer la liste des fichiers dans un fichier texte (vous pouvez alors utiliser quelque chose comme une formule Excel si vous êtes vraiment désespéré de produire une liste de commandes à coller dans cmd, ou vous-même. pourrait utiliser Excel pour transposer les cellules de sorte que tous les noms de fichiers soient sur la même ligne.)
18
Malvineous

Utilisez simplement Powershell, qui est préinstallé sur Windows 7. Powershell est capable d’exécuter des commandes cmd et comprend les caractères génériques à n’importe quel endroit du chemin.

Pour démarrer Powershell, tapez simplement "powershell" dans le champ de recherche du menu Démarrer et appuyez sur Entrée.


Si l'application attend une chaîne contenant tous les noms de fichiers, c'est le bon script:

$delimiter = " "
[string]$files = $nothing ; ls *.txt | % { $files += $_.fullname + $delimiter } ; application.exe $files

Modifiez $delimiter = " " en $delimiter = "," si votre application attend une liste de noms de fichiers séparée par des virgules.

Explication du code:

  • [string]$files = $nothing - crée une variable vide de type string
  • ; - est un séparateur pour plusieurs commandes, pas un pipeline!
  • ls *.txt | % { $files += $_.fullname + $delimiter } - obtient une liste de tous les fichiers texte et crée une chaîne avec tous les noms de fichiers séparés par le délimiteur
  • application.exe $files - appelle l'application et lui transmet la liste de fichiers

Vous pouvez même rechercher un modèle de fichier de manière récursive en ajoutant -recurse à ls *.txt afin que le code complet ressemble à ceci:

$delimiter = " "
[string]$files = $nothing ; ls *.txt -recurse | % { $files += $_.fullname + $delimiter } ; application.exe $files

Modifier:
Pour éviter les irritations, ls et dir sont des alias de Get-ChildItem et % est un alias de ForEach-Object. Je garde mon code avec des alias utilisés car ils sont plus courts.

EDIT 2018/04/25:
En 2012, je connaissais assez PowerShell. Bien sûr, il existe un moyen plus simple, bien que ce ne soit pas aussi facile que la capacité d'expansion globale de unix/linux:

app.exe $(ls *.txt | % {$_.FullName})

Explication:

  • $ () va d'abord évaluer l'expression à l'intérieur et va se remplacer par le résultat de cette expression (un peu comme les backtick le font en bash)
  • ls *.txt obtient les objets FileInfo de tous les fichiers correspondant au glob *.txt
  • powerShell étant orienté objet, nous devons générer le nom complet de chaque objet FileInfo. Nommer simplement un attribut/une propriété dans PowerShell le génère par défaut. % { $_.FileName } fait cela pour nous. % parcourt tous les éléments renvoyés par ls et génère chaque objet FileName.
9
wullxz

Cela vous donnera une liste et la mettra également dans la variable nommée expanded_list. Placez-le dans un fichier de commandes et exécutez-le avec myBatchFile name myPattern. Placez le motif avec des guillemets s'il contient des espaces. Correspond aux fichiers, pas de répertoires. Exécuter sans paramètres correspond à tous.

@echo off
set expanded_list=
for /f "tokens=*" %%F in ('dir /b /a:-d "%~1"') do call set expanded_list=%%expanded_list%% "%%F"

echo expanded_list is: 
echo %expanded_list%

Vous pouvez ensuite exécuter votre commande avec my_command_exec %expanded_list%

ATTENTION! La taille maximale de la variable cmd est de 8191 caractères (à partir de XP), il est donc possible de la dépasser! Vous ne pouvez pas compter sur l'utilitaire pour vous fournir toujours une liste complète. D'autre part, la longueur maximale de la ligne de commande est également de 8191, vous ne pourrez donc pas l'exécuter de toute façon.

7
wmz

Cela fonctionne dans cmd.exe

dir /b *.ext

ou

echo | dir /b *.ext
3
user619818

Notez que ceci est dans le commentaire aux affiches dans un fil séparé user619818 et styfle)

DIR peut et permet de rechercher dans tous les sous-répertoires les fichiers correspondant à un type spécifique.

Remarque: le répertoire racine dans lequel tous les sous-répertoires sont situés est supposé être "C:\Mon programme\Racine \", car l'auteur n'a pas indiqué de chemin d'accès sous lequel se trouvent ces répertoires.

DIR /B /S "C:\My Program\Root\*.ext"

cela donnera les chemins d'accès complets et les noms de fichiers des fichiers sources.

si vous ne voulez que les noms de fichiers, vous devrez procéder comme suit

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( Echo.%~nxA )

en supposant que vous souhaitiez déplacer tous ces fichiers de "C:\Mon programme\Racine\Sous répertoires\*. ext" vers "D:\Singlefolder\*. ext", procédez comme suit:

FOR /F "Tokens=*" %A IN ('DIR /B /S "C:\My Program\Root\*.ext"') DO @( MOVE "%~A" "D:\Singlefolder\%~nxA" /Y )

Espérons que cela aide les autres à l'avenir. :)

2
Ben Personick

C'est vieux, mais avec le sous-système Linux pour Windows, il est assez commun d'avoir bash dans votre PATH maintenant. Si tel est le cas, cela pourrait faire l'affaire pour vous:

bash -c 'cat *.txt'
1
Richard