Cómo enumerar archivos y directorios con directorios primero

22

Tengo dos preguntas. Primero, ¿qué comando enumera los archivos y directorios, pero primero los directorios?

Segunda pregunta: quiero copiar una lista de archivos en un solo directorio, pero convertir el directorio de destino en el primer nombre de archivo en el comando.

Elham abbasi
fuente
55
lsTiene un --group-directories-firstinterruptor.
jasonwryan
1
-tes posiblemente una opción solo de GNU cpque toma un directorio objetivo explícito y, por lo tanto, puede ir a cualquier parte de la línea de comando, incluido el comienzo.
jw013

Respuestas:

36

¿Tienes GNU?

La versión gnu de lshas --group-directories-first. Y cptiene -t.

No GNU?

En los sistemas que no tienen GNU ls, su mejor opción es dos llamadas sucesivas findcon -maxdepth n/ -mindepth ny -type tcon las opciones apropiadas.

find . -maxdepth 1 -mindepth 1 -type d
find . -maxdepth 1 -mindepth 1 \! -type d

Para copiar archivos, con el objetivo primero, tendría que escribir un script que guarde el primer argumento, luego use shifty agregue el argumento hasta el final.

#!/bin/sh
target="$1"
shift
cp -r -- "$@" "$target"

¡Cuidado!

Si planeaba usarlos juntos, es decir, recopilar la lista de ( findo lsposiblemente mediante el uso xargs) y pasarla a cp(o un cpcontenedor), debe tener en cuenta los peligros que conlleva analizar las listas de archivos (básicamente, los nombres de archivo pueden contienen caracteres como líneas nuevas que pueden estropear su guión). Específicamente, mira en find's -execy -print0opciones y xargs' s -0opción.

Una herramienta alternativa para copiar eficientemente árboles de directorios.

Es posible que desee considerar el uso en su rsynclugar; Tiene muchas funciones que pueden facilitar su trabajo.

Shawn J. Goff
fuente
Esto es genial. En términos más generales, ¿hay alguna forma de saber si tengo la versión GNU? (aparte de probar la opción --group-directories-first).
Amelio Vazquez-Reina
3
Puedes correr ls --versionpara averiguar cuál tienes.
Shawn J. Goff
6

Listado de directorios primero para un no GNU ls:

ls -l | sort

Tenga en cuenta que esto también enumerará todo el montón de otras cosas raras como enlaces simbólicos, tomas de corriente y tuberías (agrupadas adecuadamente, por supuesto), pero teniendo en cuenta que esas cosas son bastante raras, eso no debería ser un problema. De lo contrario, el filtro seríals -l | grep '^(-|d)' | sort

Alexander Shcheblikin
fuente
1
+1 inteligente y más corto que la respuesta aceptada. Excepto que realmente debería ser sort -r.
PythonNut
1
ls -l | el tipo no funcionó para mí en una Mac. Agrupa los directorios primero pero no los clasificó ni clasificó los nombres de archivo que siguieron.
Ray
También tenga en cuenta: utilizando el | sort` eliminará su color, ya que ahora es texto.
JayRizzo
4

funciona para bash y zsh

simplemente agregue alias en ~ / .bashrc o ~ / .zshrc

# Colorize the ls output ##
alias ls='LC_COLLATE=C ls -h --group-directories-first --color=auto'

Además, si tiene ZSH, puede usar la utilidad "k"

k -h --group-directories-first

ingrese la descripción de la imagen aquí

simplemente instálelo con antígeno, colocando lo siguiente en ~ / .zshrc

antigen bundle reduxionist/k --branch=add-sort-options
DmitrySemenov
fuente
1
Buena respuesta para ofrecer el alias.
рüффп
0

Para zshlas listas de finalización, puede establecer el list-dirs-firstestilo truepara que los directorios se muestren primero. En su ~/.zshrc:

zstyle ':completion:*' list-dirs-first true

(aquí se aplica a todos los widgets de finalización que lo admiten y para todos los comandos; puede restringir eso si lo desea, consulte la zstyledocumentación para más detalles)

Si aún no lo ha hecho, asegúrese de ejecutar compinstalltambién para obtener listas de finalización en color, con descripciones, etc. y todas las demás ventajas.

Stéphane Chazelas
fuente
0

Para no GNU, awk puede filtrar todos los demás campos:

ls -l | sort -r | awk 'NF==9 { if ($1~/^d/) { print $9 "/" } else { print $9 } }'
  • NF == 9: la salida de ls -lmust contiene 9 campos
  • si la línea comienza con 'd', imprime un '/' adicional
  • de lo contrario solo el nombre del archivo

El resultado se ve ls -1pero con los directorios puestos primero:

node_modules/
src/
e2e/
angular.json
tslint.json
package.json
README.md

De acuerdo con "El formato largo" de la página de manual de ls, cuando se involucran otros tipos de archivos, el orden de salida debe ser:

   s     Socket link.
   p     FIFO.
   l     Symbolic link.
   d     Directory.
   c     Character special file.
   b     Block special file.
   -     Regular file.

Una práctica función bash (ponla en tu .bash_profile o .bashrc):

function l1() {
  ls -l $* | sort -r | awk 'NF==9 { if ($1~/^d/) { print $9 "/" } else { print $9 } }'
}
clarkttfu
fuente