2008-09-29 21 views
7

J'ai un fichier qui répertorie les noms de fichiers, chacun sur sa propre ligne, et je veux tester si chacun existe dans un répertoire particulier. Par exemple, certaines lignes d'échantillonnage du fichier peut êtreComment puis-je tester si une liste de fichiers existe?

mshta.dll 
foobar.dll 
somethingelse.dll 

Le répertoire que je suis intéressé est X:\Windows\System32\, donc je veux voir si les fichiers suivants sont présents:

X:\Windows\System32\mshta.dll 
X:\Windows\System32\foobar.dll 
X:\Windows\System32\somethingelse.dll 

Comment puis-je faire cela en utilisant l'invite de commande Windows? Aussi (par curiosité) comment pourrais-je le faire en utilisant bash ou un autre shell Unix?

Répondre

9

En cmd.exe, la FOR/F variable%IN (nom) DOcommande devrait vous donner ce que vous voulez. Cela lit le contenu de filename (et ils pourraient être plus d'un nom de fichier) une ligne à la fois, en plaçant la ligne dans la variable% (plus ou moins, faire un HELP pour dans une invite de commande). Si personne d'autre ne fournit un script de commande, je vais essayer.

EDIT: ma tentative pour un script de cmd.exe qui fait la demande:

@echo off 
rem first arg is the file containing filenames 
rem second arg is the target directory 

FOR /F %%f IN (%1) DO IF EXIST %2\%%f ECHO %%f exists in %2 

Remarque, le script ci-dessus doit être un script; Une boucle FOR dans un fichier .cmd ou .bat, pour une raison étrange, doit avoir un double signe avant sa variable.

Maintenant, pour un script qui fonctionne avec bash | cendres | tiret | sh | ksh:

filename="${1:-please specify filename containing filenames}" 
directory="${2:-please specify directory to check} 
for fn in `cat "$filename"` 
do 
    [ -f "$directory"/"$fn" ] && echo "$fn" exists in "$directory" 
done 
1

Sous Windows:


type file.txt >NUL 2>NUL 
if ERRORLEVEL 1 then echo "file doesn't exist" 

(Cela peut ne pas être la meilleure façon de le faire, il est un moyen que je connaisse, voir aussi http://blogs.msdn.com/oldnewthing/archive/2008/09/26/8965755.aspx)

Dans Bash:


if (test -e file.txt); then echo "file exists"; fi 
+0

Son fichier.txt contient des noms de fichiers, ce n'est pas le fichier qu'il vérifie. – tzot

+0

Cette solution fonctionne très bien pour moi. Merci! –

9

Bash:

while read f; do 
    [ -f "$f" ] && echo "$f" exists 
done < file.txt 
1

Veuillez noter cependant qu'en utilisant les systèmes de fichiers par défaut sous Win32 et * nix, il n'y a aucun moyen de garantir l'atomicité de l'opération, c'est-à-dire si vous vérifiez l'existence des fichiers A, B et C ou thread peut avoir supprimé le fichier A après l'avoir passé et pendant que vous cherchiez B et C.

Les systèmes de fichiers tels que Transactional NTFS peuvent surmonter cette limitation.

1

Je voulais ajouter un petit commentaire à la plupart des solutions ci-dessus. Ils ne testent pas réellement si un fichier particulier existe ou non. Ils vérifient si le fichier existe et si vous y avez accès. Il est tout à fait possible qu'un fichier existe dans un répertoire dont vous n'avez pas la permission, auquel cas vous ne pourrez pas voir le fichier même s'il existe.

+0

Ce que vous dites est techniquement correct; Pratiquement, cependant, ce n'est pas pertinent. Si je n'ai pas les permissions pour lire/scanner un répertoire et que je ne peux donc pas y accéder pour tester son existence, quelle est la différence pour qu'il n'existe pas (pour moi)? – tzot

2
for /f %i in (files.txt) do @if exist "%i" (@echo Present: %i) else (@echo Missing: %i)