Respuestas:
Aquí hay un enfoque completamente diferente basado en GNU findy uniq. Esto es mucho más rápido y amigable con la CPU que las respuestas basadas en la ejecución de un comando de shell que cuenta archivos para cada directorio encontrado.
find . -type f -printf '%h\n' | sort | uniq -d
El findcomando imprime el directorio de todos los archivos en la jerarquía y uniqsolo muestra los directorios que aparecen al menos dos veces.
-printf '%h\0' | sort -z | uniq -zd | xargs -r0 ...
find . -type d \
-exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' \
-print
Esto encontrará todos los nombres dentro o debajo del directorio actual y luego filtrará todos los nombres que no sean nombres de directorios.
Los nombres de directorio restantes se darán a este breve script:
c=0
for n in "$1"/*; do
[ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 ))
done
[ "$c" -ge 2 ]
Este script contará el número de archivos regulares (omitiendo enlaces simbólicos) en el directorio dado como el primer argumento de línea de comando (desde find). El último comando en el script es una prueba para ver si el recuento fue 2 o mayor. El resultado de esta prueba es el valor de retorno (estado de salida) del script.
Si la prueba tuvo éxito, -printhará findque se imprima la ruta al directorio.
Para considerar también los archivos ocultos (archivos cuyos nombres comienzan con un punto), cambie la sh -csecuencia de comandos de decir
for n in "$1"/*; do
a
for n in "$1"/* "$1"/.*; do
Pruebas:
$ tree
.
`-- test
|-- a
|-- dir1
| |-- a
| |-- b
| `-- c
`-- dir2
|-- dira
|-- dirb
| |-- file-1
| `-- file-2
`-- dirc
6 directories, 6 files
$ find . -type d -exec sh -c 'c=0; for n in "$1"/*; do [ -f "$n" ] && [ ! -h "$n" ] && c=$(( c + 1 )); done; [ "$c" -ge 2 ]' sh {} ';' -print
./test/dir1
./test/dir2/dirb
[ "" -ge 2 ]es una prueba válida.
dash, bash --posixy testtodos muestran un mensaje de error y salen con 2 (es decir, "Se produjo un error")
kshfuncionaba como sh. Se enmendará de inmediato. ¡Gracias por molestarme! :-)
[ -f ... ]referencia a enlaces simbólicos. Debe agregar una prueba para eliminarlos, ya que la pregunta especifica que solo se deben contar los archivos normales.
Con la ayuda de la respuesta de Gilles sobre SU y su reversa y algunas modificaciones, aquí está lo que necesita.
find . -type d -exec sh -c 'set -- "$1"/*;X=0;
for args; do [ -f "$args" ] && X=$((X+1)) ;done; [ "$X" -gt 1 ] ' _ {} \; -print
Árbol de directorios.
.
├── test
│ ├── dir1
│ │ ├── a
│ │ ├── b
│ │ └── c
│ ├── dir2
│ │ ├── dira
│ │ │ └── a file\012with\012multiple\012line
│ │ ├── dirb
│ │ │ ├── file-1
│ │ │ └── file-2
│ │ └── dirc
│ ├── diraa
│ ├── dirbb
│ ├── dircc
│ └── x
│ └── x1
│ └── x2
└── test2
├── dir3
└── dir4
Resultado:
./test
./test/dir1
./test/dir2/dirb
testlos dir2directorios y en mi configuración de prueba (ver mi respuesta).
test/x1y test/x2como archivos también ... $1y $2serán directorios para test, y se perderá el directorio.
Otro enfoque find+ wc:
find path/currdir -maxdepth 1 -type d ! -empty ! -path "path/currdir" \
-exec sh -c 'count=$(find "$1" -maxdepth 1 -type f | wc -l); [ $count -ge 2 ]' _ {} \; -print
path/currdir - ruta a su directorio actual
-maxdepth 1- considere solo subcarpetas secundarias directas
! -empty - ignorar subcarpetas vacías
! -path "path/currdir" - ignorar la ruta actual del directorio
count=$(find "$1" -maxdepth 1 -type f | wc -l)- countse le asigna el número de archivos para cada subcarpeta encontrada
[ $count -ge 2 ] ... -print - imprimir nombre / ruta de subcarpeta que contiene 2 o más archivos regulares
find. En este caso, porque GNUfinddestrozará los nombres de directorios que tienen caracteres que no se pueden imprimir en la configuración regional actual (como "ä" en la configuración regional en C). Consulte también unix.stackexchange.com/questions/321697/…