Evite la lista de archivos que terminan con ~ (archivos de copia de seguridad)

20

Mi requisito es enumerar todos los archivos en un directorio, excepto los archivos que terminan en a ~(archivos de respaldo).

Traté de usar el comando:

ls -l | grep -v ~    

Me sale esta salida:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

Quiero obtener solo estos archivos:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt
curioso
fuente
Parece que está tratando de evitar la inclusión de archivos que terminan en a ~. Estos archivos son archivos de respaldo creados en algunos editores de texto.
ctrl-alt-delor
¿Qué sistema operativo estás utilizando? ¿Es un Gnu / Linux (como Debian, Ubuntu, Redhat, Centos, Fedora, Suse, Mint, Arch, ...)?
ctrl-alt-delor
2
Tenga en cuenta que el archivo que desea ignorar parecen ser archivos de copia de seguridad de Emacs. Es bastante fácil cambiar el comportamiento de Emacs para que guarde copias de seguridad en un directorio centralizado y no en todas partes; ver emacs.stackexchange.com/questions/33/…
Kilian Foth
Lamento ser malo pero no te creo; ls -l(letra ell) incluiría los permisos, nlinks, propietario, tamaño y modtime para cada archivo listado. Lo que produciría la salida que muestra es ls -1(dígito uno) y en muchos sistemas -1se necesita para producir una salida de una sola columna en el terminal , pero cuando lsse canaliza (como aquí grep) o se redirige, -1no es necesario, ya es una sola columna .
dave_thompson_085
@ dave_thompson_085 He truncado todo el texto, y solo los nombres de archivo aquí ... porque sentí que eso es irrelevante. Y también este es un sistema de producción (no mi propio sistema). Así que no quiero enumerar nombres de usuario, detalles y filtrarlos.
curious_one

Respuestas:

49
ls -l | grep -v ~

La razón por la que esto no funciona es que la tilde se expande a su directorio de inicio, por lo que grepnunca ve una tilde literal. (Consulte, por ejemplo, el manual de Bash sobre la expansión de Tilde ). Debe citarlo para evitar la expansión, es decir

ls -l | grep -v "~"

Por supuesto, esto eliminará las líneas de salida con tilde en cualquier lugar, incluso en el medio del nombre de un archivo o en cualquier otro lugar de la lssalida (aunque es probable que no aparezca en nombres de usuario, fechas o similares). Si realmente solo quiere ignorar los archivos que terminan en tilde, puede usar

ls -l | grep -v "~$"
ilkkachu
fuente
48

La implementación de GNU de ls(que se encuentra en la mayoría de los sistemas Linux) tiene una opción para eso: -BIgnorar las copias de seguridad:

ls --ignore-backups
hschou
fuente
24

Si está utilizando bash, asegúrese de que extglobesté habilitado:

shopt -s extglob

Entonces puedes usar:

ls -d -- !(*~)
  • -d no mostrar el contenido de los directorios
  • !(*~) todos los archivos excepto los que terminan con ~

En zsh, puede hacer lo mismo con la kshglobopción o usando sus propios globos extendidos:

setopt extended_glob
ls -d -- ^*~

Dado que el sufijo para excluir tiene solo un carácter, también puede hacer coincidir los nombres de archivo donde el último carácter no es la tilde (esto también debería funcionar sin extglob):

ls -d -- *[^~]

Pero la idea general es usar ls --ignore-backups.

Ravexina
fuente
12

Esto debería ayudar:

ls -l | grep -v '~'  

Motivo: El ~ char es reemplazado por su directorio de inicio antes de ejecutar el comando. Tratar

echo ~

y

echo '~'
Nico Mittenzwey
fuente
6

Como se mencionó en otras respuestas, la razón por la que probablemente tenga problemas es porque no citó o escapó de la tilde.

Para un caso de uso en particular, he usado la expansión de nombre de archivo de shell para hacer algo similar. Lo he estado usando desde aproximadamente 2003, lo que significa que ha funcionado en una muy amplia variedad de implementaciones de shell en diferentes tipos de sistemas. (Aquí también lo uso -Cporque quiero una buena visualización en columnas ordenadas)

ls -C *[!~]

(por supuesto, una limitación con el uso de la expansión de nombre de archivo de shell es que un directorio con un número muy grande de archivos (sin respaldo) hará que la expansión exceda el tamaño de la lista de argumentos disponibles, aunque en la mayoría de los sistemas modernos este límite es bastante alto, a menudo 250 KB o más, a veces mucho más)

Greg A. Woods
fuente
1

ls | grep -v '~$'Es la solución rápida. Utiliza ls para enumerar todos los archivos (no ocultos), luego usa grep con -v(coincidencia invertida, es decir, exclusión) para excluir todas las líneas con tilde ( ~) al final ( $).

SIN EMBARGO, si tiene CUALQUIER archivo llamado como algo1, algo2, es un GRAN indicador maloliente de que tiene un mal flujo de trabajo, que debe solucionar en la fuente, no con trucos torpes como modificar cómo funciona ls.

Si te encuentras nombrando archivos con números de versión, como test1 y test2 o testone y testtwo, entonces lo que realmente quieres es un sistema de control de versiones, como git.

Esto es especialmente cierto en su caso, donde tiene múltiples versiones de múltiples archivos, y la versión parece necesitar ser coordinada entre todos los archivos.

Los sistemas de control de versiones le permiten esencialmente superponer una ventana de tiempo en el sistema de archivos, por lo que solo ve el testarchivo, pero debajo del capó (a través del programa de control de versiones) todas las versiones están disponibles para buscar, recuperar, volver a comparar, etc. .

Una vez que haya configurado esto, ya no necesitará archivos de respaldo de su editor, porque el control de versiones tiene el historial de los archivos desde que comenzó a usarlo, incluso si ha realizado miles de cambios desde entonces. Incluso puede "ramificar" la línea de tiempo del historial, probar una nueva idea y retroceder en el tiempo y luego avanzar para probar una idea diferente, si es necesario.

por favor borrame
fuente
1

Aunque muchas respuestas son correctas (me gusta la del @Foonparticular), notaría que obtener la lista de nombres ls -les un poco flojo por varias razones.

La herramienta adecuada para encontrar archivos es, como era de esperar, find.

Uno de sus resultados es que es capaz de manejar la "lógica de selección" por sí misma, por ejemplo:

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

que literalmente dice find:

  1. Busque archivos en el directorio actual: .
  2. Solo búsquelos en el nivel de ese directorio, es decir, no repita: -maxdepth 1
  3. Allí, busca entidades, que

    • de tipo de archivo: -type f
    • y: -a
    • cuyos nombres no terminan en ~: ! -name *~ (donde !niega la siguiente directiva que coincide con los nombres de archivo -name *~).

    (Para que la coincidencia completa en tipo y nombre aparezca como una unidad lógica, se escribe entre paréntesis con (y )).

  4. Imprimir el nombre de cada archivo encontrado: -print.

Debe proteger algunos caracteres que son especiales para el shell para que no sean interpretados por el shell, y es por eso que los paréntesis y la explosión !se escapan con una barra invertida y el patrón de nombre *~está rodeado de comillas simples.

El findcomando posee un mini lenguaje muy poderoso a través del uso de sus opciones. Por ejemplo, se le puede pedir que procese recursivamente un árbol (o árboles) del sistema de archivos completo pero omita ciertos directorios durante el escaneo. Es posible hacer coincidir varios atributos de los archivos, como el tiempo de creación o modificación o el tamaño de lo que sea.

kostix
fuente