¿Cómo canalizo ls a grep y elimino los archivos filtrados por grep?

33

Quería eliminar algún paquete en mi archivo de inicio, pero el nombre del archivo era demasiado largo ( google-chrome-stable_current_i386.deb). Entonces, decidí usar el comando ls|grep chrome|rmpara canalizar los archivos a grep para filtrar el archivo de Chrome, y luego eliminarlo. No funcionó, así que me gustaría ver cómo puedo hacer esto.

SpecialBomb
fuente
22
rm -i *chrome*.deb
Lambert
28
En general, no me gusta cuando las personas publican respuestas de "no hagas eso", pero este es uno de los mejores ejemplos de un problema XY que he visto. Su verdadera pregunta es "¿cómo elimino rápidamente un archivo con un nombre de archivo largo, sin escribir todo?", Y hay muchas buenas maneras que no implican extraer el resultado dels
Michael Mrozek
55
Solo usa find- find . -name "*chrome*" -delete.
Boris the Spider
3
Mis dos centavos como usuario de StackExchange: en el futuro, haga su pregunta de una manera más genérica mientras proporciona detalles sobre lo que ha intentado. "¿Cómo elimino cualquier archivo en una carpeta con cierta cadena en el nombre del archivo?" podría haber sido una mejor manera de expresarlo. Posteriormente, se podría agregar simplemente, como un aparte, que ha intentado tuberías lsa través grepde rm, pero no pudo conseguir que funcione. De esa forma, obtendrá una o dos buenas respuestas sobre la forma "correcta" o "más fácil" de realizar su tarea en lugar de obligar a alguien a darle una buena respuesta sobre una solución ineficiente.
Adrian

Respuestas:

56

Esto casi me hizo estremecer.

  1. Es posible que desee dejar de apuntar esa escopeta a su pie. Básicamente, cualquier tipo de análisis lsserá más complicado y propenso a errores que los métodos establecidos como find [...] -execo globs .
  2. A menos que alguien instale una distribución troll para usted, su shell se ha Tabcompletado. Solo escribe rm googley presiona Tab. Si no se completa de inmediato, presione Tabnuevamente para ver una lista de archivos coincidentes. Escriba más caracteres del nombre de archivo para reducirlo hasta que se complete, luego ejecute el comando.
  3. Tuberías ! = Parámetros . La entrada estándar es un flujo de datos binarios que se puede alimentar a un comando de forma asincrónica. Los parámetros son cadenas separadas por espacios que se pasan una y solo una vez a un comando cuando se ejecuta. Estos son muy raramente intercambiables.
l0b0
fuente
1
Lo siento si parecía una pregunta n00b. Sabía que estaba bien usarlo en general, ya que el paquete indicado era el único paquete con "cromo". Por lo tanto, el uso de grep filtraría solo un archivo. Soy bastante nuevo en Linux, y ya he hecho muchos scripts de bash, pero todavía no lo sé todo: P. Duro, amigo.
SpecialBomb
55
No quería ser duro, pero el caparazón es un entorno duro e implacable, escondido detrás de una superficie fácil de usar. Hacer las cosas de manera segura es bastante difícil, no importa de manera segura o incluso correcta .
l0b0
2
@SpecialBomb Esta es la única respuesta correcta. Explicar cómo apuntar correctamente dicha escopeta para cortar limpiamente el pie, como lo hacen las otras respuestas, ciertamente no es el camino a seguir. Tenga especial cuidado de ejecutar a ciegas rm: es probablemente la forma más común de freír su distribución.
Boris the Spider
@BoristheSpider Heh, definitivamente ya he frenado Ubuntu dos veces instalando controladores de tarjeta gráfica AMD. Aunque ya hice una pregunta sobre eso. AMD ha sido horrible, así que pregunté si había soluciones comunes o mejores métodos de juego con Linux en una tarjeta AMD.
SpecialBomb
34

También puede usar el comando find con un comodín:

find . -maxdepth 1 -name '*chrome*' -delete

Tenga en cuenta que el argumento "-maxdepth" asegura que find solo funciona en el directorio actual y no se repite en subdirectorios.

cambiador
fuente
1
Sugerencias para mejoras: (a) uso -inamepara nombres de archivo que no distinguen entre mayúsculas y minúsculas (b) para xargsusar -print0flag for findy -0flag for xargs. El uso de le xargspermite hacer cosas como eliminaciones "interactivas" (¿confirmar eliminar foo?).
Christopher Schultz
3
No es necesario canalizar a xargs si usa la opción -exec:find . -name '*chrome*' -exec rm -i {} +
Johnny
44
¿No eliminará esto también recursivamente en subdirectorios? Es posible que deba especificar maxdepthque sea 1.
Tyzoid
32

Tuviste la idea correcta, te perdiste algunos detalles. Como se trata de una lista que llega a STDIN y rmespera parámetros, debe usarla xargs.

Así:

ls | grep chrome | xargs rm

Debería darte lo que quieres.

Tenga en cuenta que si desea eliminar todo lo que no sea el chromearchivo, simplemente puede agregarlo -va la grepdeclaración.

Tenga en cuenta que, según las otras respuestas a esta pregunta, esta es probablemente una mala forma de lograr lo que desea lograr.

John
fuente
Con -v, ¿no eliminaría esto todo excepto los archivos que coinciden chrome? No creo que eso sea lo que quiere el OP ...
akivajgordon
Mirando de nuevo, tienes razón. El OP quiere "filtrar el archivo de Chrome", pero luego quiere eliminarlo.
John
Esto parece innecesariamente complejo, en comparación con un simple "rm -i chrome "
chander
55
La respuesta aceptada funciona, pero vea la respuesta a continuación que explica por qué es una mala idea. (Publicar este comentario aquí solo por el bien de aquellos que se detienen tan pronto como ven una marca de verificación "aceptada")
Jim Davis
1
Esto, la respuesta aceptada "funciona" solo si no hay nombres de archivo "extraños" en la lssalida. Los nombres de archivo con espacios arruinarán esto. Esto también es peligroso si alguien puede construir un nombre de archivo con salsa especial en el directorio donde ejecuta esto. Como ya ha señalado más de una persona, ¡no analice la salida de ls !
Stephen P
11

Nunca analice la salida de ls
Mi sugerencia es evitar analizar la salida de ls [ 1 ] , incluso más si está junto con el delcomando. Esto, por muchas razones, se relaciona principalmente con caracteres inesperados y no habituales permitidos en el nombre del archivo.

Incluso cuando debe esperar que los nombres de archivo que pertenecen a los paquetes de Linux "se comporten bien" , este problema puede aparecer si otros archivos están presentes en el mismo directorio pero no lo sabía ni lo notó.

Es mejor usar findla expansión de pestañas (comience a escribir el nombre y presione Tab), la expansión del nombre de archivo [ 2 ] como *MyKey*...


Una solución rápida
Dado que desea seleccionar todos los paquetes (que terminan con .deb) con "google" dentro, puede crear su solicitud con el comodín * *google*.deby hacer un simple

rm -i *google*.deb 

que seleccionará cada nombre de archivo con "google" en el medio que finalizará para estar .debpresente en el directorio actual. La opción -i(interactiva) solicitará la confirmación, un buen hábito cuando elimina archivos con la expansión de parámetros.


Una solución cercana a la filosofía de su intento
Si su propósito es construir su línea de comando pieza tras pieza, de modo que lo haya hecho ls, después ls | grep googley solo después de verificar su salida , puede ejecutarlo en una subshell $(...)con

rm -i $(ls | grep google)

Una forma más rápida y peligrosa [ 3 ] es utilizar!!

ls | grep google
rm -i $(!!)

que ejecutará el último comando terminado en su historial . Puede protegerse del hecho de que no tiene control visual de la línea que va a ejecutar si ha habilitado de antemano las opciones de shell histverifycon shopt -s histverify.

Hastur
fuente
5
touch 0 1 2 3 4 5 6 7 8 9
find . -name \[0-9] -ok rm {} \;

< rm ... ./0 > ? y
< rm ... ./9 > ? y
< rm ... ./8 > ? y
< rm ... ./7 > ? y
< rm ... ./6 > ? y
< rm ... ./5 > ? y
< rm ... ./4 > ? y
< rm ... ./3 > ? y
< rm ... ./2 > ? y
< rm ... ./1 > ? y
^C

... use -name '*c*.deb'o algún otro patrón que más le convenga.

mikeserv
fuente
2

rmno acepta entradas de stdin. Tendrás que hacer algo comols google-chrome* | xargs rm

David King
fuente