¿Cómo puedo probar si existe una lista de archivos?
-
02-07-2019 - |
Pregunta
Tengo un archivo que enumera nombres de archivos, cada uno en su propia línea, y quiero probar si cada uno existe en un directorio en particular. Por ejemplo, algunas líneas de muestra del archivo pueden ser
mshta.dll
foobar.dll
somethingelse.dll
El directorio que me interesa es X: \ Windows \ System32 \
, por lo que quiero ver si existen los siguientes archivos:
X:\Windows\System32\mshta.dll
X:\Windows\System32\foobar.dll
X:\Windows\System32\somethingelse.dll
¿Cómo puedo hacer esto usando el símbolo del sistema de Windows? Además (por curiosidad), ¿cómo haría esto usando bash u otro shell de Unix?
Solución
En cmd.exe, la FOR / F% variable IN ( filename ) DO command debería darle lo que desea. Esto lee el contenido de nombre de archivo (y podrían ser más de un nombre de archivo) una línea a la vez, colocando la línea en% variable (más o menos; haga una AYUDA PARA en el símbolo del sistema). Si nadie más proporciona un script de comando, lo intentaré.
EDITAR: mi intento de un script cmd.exe que haga lo solicitado:
@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
Nota, la secuencia de comandos anterior a debe ser una secuencia de comandos; un bucle FOR en un archivo .cmd o .bat, por alguna extraña razón, debe tener signos de porcentaje doble antes de su variable.
Ahora, para un script que funciona con bash | ash | dash | 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
Otros consejos
Bash:
while read f; do
[ -f "$f" ] && echo "$f" exists
done < file.txt
for /f %i in (files.txt) do @if exist "%i" (@echo Present: %i) else (@echo Missing: %i)
En Windows:
type file.txt >NUL 2>NUL
if ERRORLEVEL 1 then echo "file doesn't exist"
(Esta puede no ser la mejor manera de hacerlo; es una forma que conozco; vea también http://blogs.msdn.com/oldnewthing/archive/2008/09/26/8965755.aspx )
En Bash:
if ( test -e file.txt ); then echo "file exists"; fi
Tenga en cuenta, sin embargo, que al usar los sistemas de archivos predeterminados en Win32 y * nix no hay forma de garantizar la atomicidad de la operación, es decir, si verifica la existencia de los archivos A, B y C, alguna otra el proceso o el hilo podrían haber eliminado el archivo A después de pasarlo y mientras buscaba B y C.
Los sistemas de archivos como Transactional NTFS pueden superar esto limitación.
Quería agregar un pequeño comentario a la mayoría de las soluciones anteriores. En realidad, no están probando si un archivo en particular existe o no. Están verificando si el archivo existe y usted tiene acceso a él. Es completamente posible que exista un archivo en un directorio para el que no tiene permiso, en cuyo caso no podrá ver el archivo aunque exista.