Come convoglio ls a grep ed elimino i file filtrati da grep?


33

Volevo cancellare qualche pacchetto nel mio file home, ma il nome del file era troppo lungo ( google-chrome-stable_current_i386.deb). Quindi, ho deciso di utilizzare il comando ls|grep chrome|rmper reindirizzare i file in grep per filtrare il file chrome e quindi rimuoverlo. Non ha funzionato, quindi vorrei vedere come posso farlo.


22
rm -i *chrome*.deb
Lambert,

28
In generale, non mi piace quando le persone pubblicano risposte "non farlo", ma questo è uno dei migliori esempi di un problema XY che abbia mai visto. La tua vera domanda è "come faccio a eliminare rapidamente un file con un lungo nome di file, senza digitare il tutto", e ci sono molti buoni modi che non comportano il grepping dell'output dals
Michael Mrozek

5
Usa solo find- find . -name "*chrome*" -delete.
Boris the Spider l'


3
I miei due centesimi come utente StackExchange: in futuro, poni la tua domanda in modo più generico fornendo dettagli su ciò che hai provato. "Come posso eliminare qualsiasi file in una cartella con una determinata stringa nel nome del file?" avrebbe potuto essere un modo migliore per esprimerlo. Quindi potresti semplicemente aggiungere, a parte, a cui hai provato lsa grepeseguire il piping rmma non riesci a farlo funzionare. In questo modo otterrai una o due buone risposte sul modo "corretto" o "più semplice" per svolgere il tuo compito piuttosto che forzare qualcuno a darti una buona risposta su una soluzione inefficiente.
Adrian,

Risposte:


56

Questo mi ha fatto quasi sussultare.

  1. Potresti voler smettere di indicarlo fucile al piede. Fondamentalmente qualsiasi tipo di analisi lssarà più complicato e soggetto a errori rispetto a metodi consolidati come find [...] -execo globs .
  2. A meno che qualcuno non abbia installato una distribuzione troll per te, la tua shell ha il Tabcompletamento. Basta digitare rm googlee premere Tab. Se non viene completato immediatamente, premere di Tabnuovo per visualizzare un elenco di file corrispondenti. Digita più caratteri del nome file per restringerlo fino al completamento, quindi esegui il comando.
  3. Tubi ! = Parametri . L'input standard è a flusso di dati binari che può essere inviato a un comando in modo asincrono. I parametri sono stringhe separate da spazio che vengono passate una e una sola volta a un comando durante l'esecuzione. Questi sono molto raramente intercambiabili.

1
Scusa se mi è sembrata una domanda n00b. Sapevo che andava bene usare in generale, dato che il pacchetto dichiarato era l'unico pacchetto con "chrome" indicato in esso. Pertanto, l'utilizzo di grep eliminerebbe solo un file. Sono abbastanza nuovo su Linux, e ho già fatto molti script bash, ma non so ancora tutto: P. Duro, amico.
SpecialBomb,

5
Non intendeva essere duro, ma la shell è un ambiente duro e spietato, nascosto dietro una superficie di facile utilizzo. Fare le cose in sicurezza è abbastanza difficile, non importa in modo sicuro o addirittura corretto .
l0b0

2
@SpecialBomb Questa è l'unica risposta corretta. Spiegare come mirare correttamente a detto fucile per tagliare chiaramente il piede, come fanno le altre risposte, non è certo la strada da percorrere. Prestare particolare attenzione all'esecuzione alla cieca rm: è probabilmente il modo più comune per friggere la distribuzione.
Boris the Spider l'

@BoristheSpider Heh, sicuramente ho già fritto Ubuntu due volte installando i driver della scheda grafica AMD. Ho già fatto una domanda a riguardo. AMD è stato orribile, quindi ho chiesto se ci fossero correzioni comuni o metodi migliori di gioco con Linux su una scheda AMD.
SpecialBomb

34

Puoi anche usare il comando find con un carattere jolly:

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

Si noti che l'argomento "-maxdepth" garantisce che find funzioni solo nella directory corrente e non ricorre nelle sottodirectory.


1
Suggerimenti per miglioramenti: (a) usare -inameper nomi di file senza distinzione tra maiuscole e minuscole (b) pipe per xargsusare -print0flag for finde -0flag for xargs. L'uso di xargsti permette di fare cose come "interattive" (confermare cancellare foo?) Cancella .
Christopher Schultz,

3
Non è necessario eseguire il pipe su xargs se si utilizza l'opzione -exec:find . -name '*chrome*' -exec rm -i {} +
Johnny il

4
Questo non eliminerà anche ricorsivamente nelle sottodirectory? Potrebbe essere necessario specificare maxdepthdi essere 1.
Tyzoid

32

Hai avuto l'idea giusta, mancavano solo alcuni dettagli. Dal momento che hai a che fare con un elenco in arrivo su STDIN erm prevede parametri, devi usarlo xargs.

Così:

ls | grep chrome | xargs rm

Dovresti darti quello che vuoi.

Si noti che se si desidera eliminare qualsiasi cosa diversa dal chromefile, è possibile semplicemente aggiungere -vagrep dichiarazione.

Si noti che, per le altre risposte a questa domanda, questo è probabilmente un cattivo modo di realizzare ciò che si desidera realizzare.


Con -v, questo non eliminerebbe tutto tranne i file corrispondenti chrome? Non credo sia quello che vuole l'OP ...
Akivajgordon,

Guardando di nuovo, hai ragione. L'OP vuole "filtrare il file Chrome", ma poi vuole rimuoverlo.
Giovanni,

Questo sembra inutilmente complesso, rispetto a un semplice "rm -i chrome "
chander

5
La risposta accettata funziona, ma vedi la risposta sotto che spiega perché è una cattiva idea. (Pubblicando questo commento qui solo per il gusto di coloro che si fermano non appena vedono un segno di spunta "accettato".)
Jim Davis,

1
Questo, la risposta accettata "funziona" solo se non ci sono nomi di file "strani"ls nell'output. I nomi di file con spazi distruggeranno questo. Questo è anche pericoloso se qualcuno può costruire un nome file con salsa speciale nella directory in cui viene eseguito. Come più persone hanno già sottolineato, non analizzare l'output di ls !
Stephen P,

11

Non analizzare mai l'output di ls Il
mio suggerimento è di evitare di analizzare l'output di ls [ 1 ] , ancora di più se in combinazione condel comando. Questo per molte ragioni principalmente legate a caratteri imprevisti e non usuali consentiti nel nome del file.

Anche quando dovresti aspettarti che i nomi dei file appartenenti ai pacchetti Linux "si comportino bene" , questo problema può comunque apparire se altri file sono presenti nella stessa directory ma non lo sapevi o non lo notavi.

È meglio usare find, l'espansione della scheda (iniziare a scrivere il nome e premere Tab), l' espansione del nome del file [ 2 ] come *MyKey*...


Una soluzione veloce
Dato che vuoi selezionare tutti i pacchetti (che finiscono con .deb) con "google" all'interno puoi costruire la tua richiesta con il jolly * *google*.debe fare un semplice

rm -i *google*.deb 

che selezionerà ogni nome di file con "google" nel mezzo che finirà per .debpresente nella directory corrente. L'opzione -i(interattiva) richiederà la conferma, una buona abitudine quando si eliminano i file con l'espansione del parametro.


Una soluzione vicina alla filosofia del tuo tentativo
Se il tuo scopo è quello di costruire il tuo pezzo da riga di comando pezzo dopo pezzo, così hai fatto ls, dopo ls | grep google, e solo dopo aver verificato il tuo output puoi eseguirlo in una subshell $(...)con

rm -i $(ls | grep google)

Un modo più rapido e pericoloso [ 3 ] è quello di utilizzare!!

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

che eseguirà l'ultimo comando finito nella tua cronologia . Puoi proteggerti dal fatto che non hai alcun controllo visivo della linea che eseguirai se hai abilitato in anticipo le opzioni di shell histverifycon shopt -s histverify.


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

... usa -name '*c*.deb'o qualche altro modello come preferisci invece.


2

rmnon accetta input da stdin. Dovrai fare qualcosa del generels google-chrome* | xargs rm

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.