Comment diriger ls vers grep et supprimer les fichiers filtrés par grep?

33

Je voulais supprimer un paquet dans mon fichier d'accueil, mais le nom de fichier était trop long ( google-chrome-stable_current_i386.deb). J'ai donc décidé d'utiliser la commande ls|grep chrome|rmpour diriger les fichiers vers grep pour filtrer le fichier chrome, puis le supprimer. Cela n'a pas fonctionné, donc j'aimerais voir comment je peux y arriver.

SpecialBomb
la source
22
rm -i *chrome*.deb
Lambert
28
D'une manière générale, je n'aime pas quand les gens publient des réponses «ne fais pas ça», mais c'est l'un des meilleurs exemples d'un problème XY que j'ai jamais vu. Votre vraie question est "comment puis-je supprimer rapidement un fichier avec un nom de fichier long, sans taper le tout", et il existe de nombreuses bonnes façons qui n'impliquent pas de saluer la sortie dels
Michael Mrozek
5
Utilisez simplement find- find . -name "*chrome*" -delete.
Boris the Spider du
3
Mes deux cents en tant qu'utilisateur StackExchange: à l'avenir, posez votre question de manière plus générique tout en fournissant des détails sur ce que vous avez essayé. "Comment puis-je supprimer des fichiers dans un dossier avec une certaine chaîne dans le nom de fichier?" aurait pu être une meilleure façon de le formuler. Ensuite, vous pouvez simplement ajouter, en lspassant , que vous avez essayé de passer grepà travers, rmmais que vous ne pouvez pas le faire fonctionner. De cette façon, vous obtiendrez une ou deux bonnes réponses sur la façon "correcte" ou "la plus simple" d'accomplir votre tâche plutôt que de forcer quelqu'un à vous donner une bonne réponse sur une solution inefficace.
Adrian

Réponses:

56

Cela m'a presque fait grimacer.

  1. Vous voudrez peut-être arrêter de pointer ce fusil de chasse à votre pied. Fondamentalement, tout type d'analyse de lsva être plus compliqué et sujet aux erreurs que les méthodes établies comme find [...] -execou globs .
  2. À moins que quelqu'un n'ait installé une distribution de troll pour vous, votre shell est Tabterminé. Tapez rm googleet appuyez sur Tab. S'il ne se termine pas immédiatement, appuyez à Tabnouveau pour voir une liste des fichiers correspondants. Tapez plus de caractères du nom de fichier pour le réduire jusqu'à ce qu'il se termine, puis exécutez la commande.
  3. Pipes ! = Paramètres . L'entrée standard est un flux de données binaires qui peut être envoyé à une commande de manière asynchrone. Les paramètres sont des chaînes séparées par des espaces qui sont transmises une et une seule fois à une commande lors de son exécution. Celles-ci sont très rarement interchangeables.
l0b0
la source
1
Désolé si cela ressemblait à une question n00b. Je savais qu'il était correct d'utiliser généralement, car le package indiqué était le seul package avec "chrome" indiqué. Par conséquent, l'utilisation de grep ne filtrerait qu'un seul fichier. Je suis assez nouveau sur linux, et j'ai déjà fait plein de scripts bash, mais je ne sais pas encore tout: P. Dur, mec.
SpecialBomb
5
Cela ne voulait pas dire être dur, mais la coque est un environnement dur et impitoyable, caché derrière une surface un peu conviviale. Faire les choses en toute sécurité est déjà assez difficile, tant pis en toute sécurité ou même correctement .
l0b0
2
@SpecialBomb C'est la seule bonne réponse. Expliquer comment viser correctement ledit fusil de chasse pour couper proprement son pied, comme le font les autres réponses, n'est certainement pas la voie à suivre. Soyez particulièrement prudent lors de l'exécution aveugle rm- c'est probablement la façon la plus courante de faire frire votre distribution.
Boris the Spider du
@ BoristheSpider Heh, j'ai certainement déjà fait frire Ubuntu deux fois en installant des pilotes de carte graphique AMD. J'ai déjà posé une question à ce sujet. AMD a été horrible, j'ai donc demandé s'il y avait des correctifs communs ou de meilleures méthodes de jeu avec Linux sur une carte AMD.
SpecialBomb
34

Vous pouvez également utiliser la commande find avec un caractère générique:

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

Notez que l'argument "-maxdepth" garantit que la recherche ne fonctionne que dans le répertoire en cours et ne récursive pas dans les sous-répertoires.

chander
la source
1
Suggestions d'améliorations: (a) utilisation -inamepour les noms de fichiers insensibles à la casse (b) rediriger vers l' xargsutilisation de -print0flag for findet -0flag for xargs. L'utilisation de xargsvous permet d'effectuer des opérations telles que les suppressions "interactives" (confirmer la suppression foo?).
Christopher Schultz
3
Pas besoin de diriger vers xargs si vous utilisez l'option -exec:find . -name '*chrome*' -exec rm -i {} +
Johnny
4
Cela ne sera-t-il pas également supprimé récursivement dans les sous-répertoires? Vous devrez peut-être spécifier maxdepth1.
Tyzoid
32

Vous avez eu la bonne idée, juste raté quelques détails. Puisque vous avez affaire à une liste venant sur STDIN et rmattend des paramètres, vous devez utiliser xargs.

Ainsi:

ls | grep chrome | xargs rm

Devrait vous donner ce que vous voulez.

Notez que si vous souhaitez supprimer tout autre que le chromefichier, vous pouvez simplement ajouter -và l' grepinstruction.

Notez que, selon les autres réponses à cette question, c'est probablement une mauvaise façon d'accomplir ce que vous voulez accomplir.

John
la source
Avec -v, cela ne supprimerait-il pas tout sauf les fichiers qui correspondent chrome? Je ne pense pas que c'est ce que le PO veut ...
akivajgordon
En regardant à nouveau, vous avez raison. L'OP veut "filtrer le fichier chrome", mais veut ensuite le supprimer.
John
Cela semble inutilement complexe, comparé à un simple "rm -i chrome "
chander
5
La réponse acceptée fonctionne, mais voir la réponse ci-dessous qui explique pourquoi c'est une mauvaise idée. (Publier ce commentaire ici uniquement pour ceux qui s'arrêtent dès qu'ils voient une coche "acceptée".)
Jim Davis
1
Ceci, la réponse acceptée "ne fonctionne" que s'il n'y a pas de noms de fichiers "bizarres" dans la lssortie. Les noms de fichiers avec des espaces vont détruire cela. Cela est également dangereux si quelqu'un peut construire un nom de fichier avec une sauce spéciale dans le répertoire où vous l'exécutez. Comme plusieurs personnes l'ont déjà souligné, n'analysez pas la sortie de ls !
Stephen P
11

Ne jamais analyser la sortie de ls
Ma suggestion est d' éviter d'analyser la sortie de ls [ 1 ] , encore plus si elle est associée à la delcommande. Ceci pour de nombreuses raisons principalement liées aux caractères inattendus et inhabituels autorisés dans le nom de fichier.

Même lorsque vous vous attendez à ce que les noms de fichiers appartenant aux packages Linux "se comportent bien" , ce problème peut néanmoins apparaître si d'autres fichiers sont présents dans le même répertoire mais que vous ne saviez pas ou ne remarquiez pas.

Il est préférable d'utiliser find, l'expansion de l'onglet (commencez à écrire le nom et appuyez sur Tab), l' expansion du nom de fichier [ 2 ] comme *MyKey*...


Une solution rapide
Puisque vous voulez sélectionner tous les packages (qui se terminent par .deb) avec "google" à l' intérieur, vous pouvez créer votre demande avec le caractère générique * *google*.debet faire un simple

rm -i *google*.deb 

qui sélectionnera chaque nom de fichier avec "google" au milieu qui se terminera pour être .debprésent dans le répertoire courant. L'option -i(interactive) vous demandera la confirmation, une bonne habitude lorsque vous supprimez des fichiers avec l'extension de paramètre.


Une solution proche de la philosophie de votre tentative
Si votre but est de construire votre ligne de commande pièce après pièce, donc vous l'avez fait ls, après ls | grep google, et seulement après avoir vérifié votre sortie, vous pouvez l'exécuter en sous-shell $(...)avec

rm -i $(ls | grep google)

Un moyen plus rapide et plus dangereux [ 3 ] , consiste à utiliser!!

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

qui exécutera la dernière commande terminée dans votre historique . Vous pouvez vous protéger du fait que vous n'avez aucun contrôle visuel de la ligne que vous allez exécuter si vous avez activé à l'avance les options du shell histverifyavec shopt -s histverify.

Hastur
la source
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

... utilisez -name '*c*.deb'plutôt un autre modèle qui vous convient.

Mikeserv
la source
2

rmn'accepte pas les entrées de stdin. Vous devrez faire quelque chose commels google-chrome* | xargs rm

David King
la source