Recorrer archivos excluyendo directorios

11

Necesito que mi script haga algo en cada archivo en el directorio actual, excluyendo cualquier subdirectorio.

Por ejemplo, en la ruta actual, hay 5 archivos, pero 1 de ellos es una carpeta (un subdirectorio). Mi script debe activar un comando dado como argumento al ejecutar dicho script. Es decir, "bash script wc -w" debería dar el recuento de palabras de cada archivo en el directorio actual, pero no de ninguna de las carpetas, para que la salida nunca tenga ninguna de las líneas "/ sub / dir: Is a directory".

Mi guión actual:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

Solo necesito excluir directorios para el bucle, pero no sé cómo.

Tõnis Piip
fuente

Respuestas:

11
#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Tenga en cuenta que también excluye los archivos que son de tipo enlace simbólico y donde el enlace simbólico se resuelve en un archivo de tipo directorio (que es probablemente lo que desea).

Alternativa (de los comentarios), verifique solo los archivos:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done
laktak
fuente
@roaima buena idea!
laktak
2
Mejor de usar if [ -f "$file" ]; then .... No un directorio devolvería no solo archivos normales sino también sockets y enlaces simbólicos.
JRFerguson
@JRFerguson basado en la pregunta del OP, diría que incluir tomas de corriente y tuberías sería una muy mala idea. En cuanto a los enlaces simbólicos, estos ya están implícitamente incluidos ! -d.
roaima
Usé [-f $ archivo] en mi script final. Tenga en cuenta la falta de comillas en la condición if. Casi en todas partes que miré tenía comillas alrededor de $ file, sin embargo, tuve que eliminarlas para que mi script funcionara.
Tõnis Piip
3

Aquí hay una alternativa al uso de un bucle for si lo que necesita hacer es simple (y no implica establecer variables en el shell principal & c).

Se puede utilizar findcon -execy utilizar -maxdepth 1para evitar de manera recursiva en el subdirectorio.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

El [ -n "$1" ]está ahí para evitar la ejecución de todos los archivos en el directorio cuando la secuencia de comandos no se pasa ningún argumento.

Gregory Nisbet
fuente
2

En zsh, puede usar calificadores globales para restringir las coincidencias con comodines por tipo de archivo. Por ejemplo, agregar (.)después del patrón lo restringe a los archivos normales.

wc -w *(.)

Para hacer frente a los nombres de archivo que comienzan con -o ., use wc -c -- *(.N)o wc -c ./*(.N). Si desea incluir también enlaces simbólicos a archivos normales, hágalo *(-.).

Los otros shells comunes no tienen esa característica, por lo que debe usar un mecanismo diferente para filtrar por archivo, como probar los tipos de archivos en un bucle o find.

Gilles 'SO- deja de ser malvado'
fuente
0

Bash para bucle excluyendo subdirectorios ('/') y enlaces (@):

for f in `ls|egrep -v '/|@'`; do echo $f; done
James Armstrong
fuente