Rilevamento di pattern alla fine di una linea con grep


65

Se lo faccio:

$ ls -R
.:
4Shared/  Cloud/

./4Shared:
UFAIZLV2R7.part3.rar

./Cloud:
UFAIZLV2R7.part2.rar.part
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part4.rar.part

Se voglio elencare .rarsolo i file e utilizzo grep , questo mostrerà anche a me i .rar.partfile, cosa non è il mio desiderio.
Sto risolvendo usando findo ls **/*.rarcome detto in questo thread e funzionano bene, ma vorrei sapere se è possibile farlo tramite grep.

Ho provato (pensando EOL):

ls -R | grep ".rar\n"

senza risultati.
Penso che il problema risieda nello scoprire se il greping si trova alla fine della linea , ma non sono sicuro.

Qualche aiuto qui, per favore?


Perché vorresti usare grepin questo caso? Perché no find?
Devnull,

1
@devnull, sapere come rilevare modelli che si trovano solo alla fine di una riga potrebbe essere utile in molti casi. Ad esempio: portabilità, utilizzo nei router con Linux troppo semplicistico incorporato, utilizzo con UnxUtils per Windows (il suo findcomando è in conflitto con quello di Windows) e ... apprendimento ;-). La domanda non riguarda "Elencare i file in una directory" (che è solo un esempio personalizzato) ma piuttosto "Comprendere l'utilizzo del comando grep"
Sopalajo de Arrierez,

1
onestamente, se stai contando alla fine di una riga per essere il tuo separatore, allora dovresti usare ls -1R.
Mikeserv,

1
E non hai nemmeno bisogno grep. Vedi la mia risposta
Mikeserv,

@mikeserv, cosa potrebbe succedere senza l' -1Rinterruttore. Apparentemente i risultati sono gli stessi.
Sopalajo de Arrierez,

Risposte:


89

L' $ancoraggio corrisponde alla fine di una linea.

ls -R | grep '\.rar$'

Puoi anche usare findper questo:

find . -name '*.rar'

Non ho realizzato il "." deve essere evaso in grep. È trattato come un jolly?
thebunnyrules,

1
@thebunnyrules "." in regex significa uno di qualsiasi personaggio.
Giordania,

10

Oltre alla tua domanda, tieni presente che .rarnon corrisponde solo a ".rar" ma corrisponde a ogni singolo personaggio (incluso .) prima del rar. In questo caso probabilmente non è un problema, ma .deve essere evaso in regex.

ls -R | grep "\.rar$"

Intendevi che .ascè come un *ascmodello? Quindi corrisponderà, ad esempio whereverasc,.
Sopalajo de Arrierez,

2
@SopalajodeArrierez No, non corrisponde a tutti i gruppi di personaggi ma a ogni singolo personaggio, ad es xrar.
Hauke ​​Laging,

5

Puoi anche incaricare grepdi cercare la tua stringa iniziando da un limite di parole. A .è uno di questi confini.

$ ls -R | grep '\brar$'

Esempio

Supponiamo di avere questi dati di esempio.

$ ls -1
afile.rar
xrar
UFAIZLV2R7.part1.rar.part
UFAIZLV2R7.part2.rar.part

Questo comando troverebbe solo il file con l' .rarestensione.

$ ls -R | grep '\brar$'
afile.rar

Come funziona?

Il metacarattere \bè un'ancora come il cursore e il simbolo del dollaro. Corrisponde a una posizione che si chiama "limite di parola". Questa partita ha lunghezza zero.

Situazioni in cui questo non funzionerà

Se si dispone di file denominati anche blah-rarquesti verranno rilevati.

$ ls -R | grep '\brar$'
afile-rar
afile.rar

Questo perché i caratteri diversi da quelli alfanumerici sono in genere considerati caratteri di confine e quindi scivolano oltre questo approccio.


Sembra essere lo stesso a prima vista, ma è leggermente diverso, anzi. Grazie, @slm. Mi dà fastidio se uso virgolette doppie "anziché semplici?
Sopalajo de Arrierez,

1
@SopalajodeArrierez - no funziona in entrambi i modi. Questo troverà tutti i file che possono essere nominati a partire da / .rar. Ma questi non saranno un problema con l'uso di ls -R. Solo se ti è capitato di usare ls -Ra.
slm

Uno di voi sarebbe interessato a spiegare questa leggera differenza al pubblico?
Hauke ​​Laging,

@HaukeLaging Il -Ppassaggio a grepnel mio esempio. Ciò innesca l'interpretazione PCRE dell'argomento.
slm

1
@SopalajodeArrierez - se un file contiene un carattere di nuova riga ( \n) che è un carattere legale. Questo ls -1Rforzerà la visualizzazione dei file in una singola colonna a prescindere.
slm

0

Basta fare :

ls -1R -I"?" -I"??" -I"???" -I"*[!.][!r][!a][!r]"

Non è necessario grepaffatto.

NOTA: quanto sopra funziona ... tranne per il fatto che ottiene almeno afile-rar e non capisco perché. Lascio qui, ma non ne vado fiero. In ogni caso, come altri hanno già detto:

find . '*.rar'

Questo non ha bloccato i file con nome xraro afile-rar.
slm

Sto ancora ottenendo gli altri file nell'output.
slm

@slm Quali altri file? Penso che potrebbe essere perché sono troppo corti. L'ho appena notato. Ho risolto anche quello.
Mikeserv,

I file afile-rare xrarsono ancora inclusi nell'output. Nessuna modifica con le tue ultime mod. Problema fastidioso no? È divertente provare a risolverlo senza i metodi regolari Cool
slm

@slm Sì, è per questo che vengo qui. Non capisco perché ci -dashriesca. La xrarcosa che potrei gestire, ma non il -dash.non capisco il-dash.
mikeserv

0

Usa virgolette singole per far funzionare $ come end-of-line. Se vuoi grep anche con qualche variabile, usa la combinazione di virgolette doppie e singole come di seguito:

grep "$var"'$'

Il mio post precedente è stato eliminato dicendo che è duplicato. Lasciami spiegare come questo è diverso.

Gli altri post menzionano l'uso completo di virgolette doppie ""o l'uso completo di virgolette singole ''. Entrambi hanno i loro limiti. Di seguito lo spiega.

Il problema con tutte le doppie virgolette è il seguente: grep "pattern$"dà il seguente errore:Illegal variable name.

E usando tutte le virgolette singole funziona, ma se si desidera la sostituzione variabile, tutte le virgolette singole non funzioneranno. Per esempio:

Se ho una stringa A_BOOK, comprese altre stringhe in un file FILE.

$ cat FILE
A_BOOK
B_BOOK_NOT_LAST
C_BOOK

Se ho impostato il BOOK su una variabile BK

set BK = BOOK

Se grep con tutte le virgolette doppie, ottengo il seguente errore:: grep "${BK}$" FILE*$ 1 per la sostituzione della variabile, 2 ° per la fine del modello ( nome della variabile non valido ).

Se grep con tutte le virgolette singole, la sostituzione della variabile non avviene. grep '${BK}$' FILEnon restituisce nulla

Se uso una combinazione di virgolette doppie e singole, ottengo ciò che mi aspetto. Virgolette doppie per la sostituzione variabile e virgolette singole per la fine del modello.

$ grep "${BK}"'$'  # << gives expected output
A_BOOK
C_BOOK

Sembra che tu stia usando csh. La "foo$"sintassi funziona bene su sh e famiglia.
Olorin,

Sì Olorin. Sto usando tcsh. Grazie per averlo indicato.
user274900,

0

Se dopo aver seguito quanto sopra e nulla funziona, potrebbe essere dovuto a terminazioni di riga. Per risolvere, fai: dos2unix pr0n.txte fai di grepnuovo il tuo .

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.