
Tengo un directorio llamado 'dir' y hay un subdirectorio llamado 'subdir'. Subdir tiene muchos archivos. Me gustaría escribir una lista de estos archivos en un archivo CSV y guardarlo en el directorio 'dir' con una línea de comando en Linux. Mi código crea el archivo csv pero lo guarda en el subdirectorio pero no en el directorio. ¿Dónde hago mal? Estoy en el directorio dir;
dir$ ls subdir >names.csv
Respuesta1
Como alternativa más sencilla, puedes cd para subdirigir y usar
printf "%s\n" * >../list.csv
Esto le dará una lista separada por una nueva línea y terminada por una nueva línea sin comas. Puede verlo como un archivo csv degradado con una sola columna.
Si desea incluir archivos ocultos (archivos con nombres que comienzan con un punto), puede utilizar * .*
en lugar del único *
. Si desea excluir el . y .. nombres de directorio, utilícelos * .[^.]* ..?*
en su lugar. En total:
printf "%s\n" * >../list.csv # For non-hidden files.
printf "%s\n" * .* >../list.csv # For all files.
printf "%s\n" * .[^.]* ..?* >../list.csv # For all files but `.` and `..`.
Pero tenga en cuenta que los nombres de archivos en Linux pueden contener nuevas líneas por sí mismos. De hecho, el único separador de un solo byte único para los nombres de archivos es el byte nulo.
Actualización debido aeste comentario:
Supongamos que tiene cualquier número de subdirectorios cuyo contenido no oculto desea catalogar en archivos separados en el directorio principal común. (Recopilar todos los nombres en un archivo es mucho más corto, consulteesta elegante solución. Y, a decir verdad, no he leído su comentario con suficiente atención). Esto se puede lograr en ese directorio principal (dir en su caso) mediante
find . -mindepth 1 -maxdepth 1 -type d -exec bash -c 'cd {}; printf "%s\n" * >../$(basename {}).csv' \;
Esto requiere los programas find
, bash
y basename
.
Al usarlo, debe tener especial cuidado, ese directorio no contiene archivos cuyos nombres entren en conflicto con las listas csv generadas automáticamente.
Así es como funciona: find
considera cada archivo que se encuentra exactamente un nivel de directorio debajo del directorio actual ( .
) —eso es lo que -mindepth 1 -maxdepth 1
hace—: Si es un directorio ( -type d
) ejecuta ( -exec
) el comando entre -exec
y el final \;
después de sustituir las llaves vacías ( {}
) por el nombre de ese directorio. Si denotamos este nombre por <SUBDIR>
, esto resulta en
bash -c 'cd <SUBDIR>; printf "%s\n" * >../$(basename <SUBDIR>).csv'
Esto comienza bash
en un subproceso, lo que hace que ejecute el argumento de la -c
opción como un script de shell, es decir
cd <SUBDIR>;
printf "%s\n" * >../$(basename <SUBDIR>).csv
que es prácticamente lo mismo que el anterior. Aquí, la expresión
$(basename <SUBDIR>)
se expande al nombre base de <SUBDIR>
. Esto es necesario porque <SUBDIR>
iterará a través de ./subdir1, ./subdir2, etc. en su caso. Los nombres base correspondientes son subdir1, subdir2, etc.
Respuesta2
Debes lograrlo usando elparabucle.
Si tengo entendido que es correcto, desea obtener una lista de archivos en el subdirectorio. Entonces haz algo como esto:
$ cd dir
$ for files in subdir/*;do echo $files|cut -d '/' -f 2 >>filelist.csv;done
Ahora, puede ver que se ha creado un archivo llamado "filelist.csv" en su directorio de directorio.