Come utilizzare grep su tutti i file in modo non ricorsivo in una directory?

10

Voglio cercare una stringa di testo in tutti i file in una directory (e non nelle sue sottodirectory, so che l'opzione -r lo fa, ma non è quello che voglio).

  1. Esecuzione

    grep "string" /path/to/dir
    

    dovrebbe essere in grado di farlo, ho letto, ma mi dà l'errore:

    grep: dir: è una directory

  2. Successivamente, ho provato a eseguire grep su più file.

    grep "string" .bashrc .bash_aliases funziona perfettamente.

    grep "string" .bash* funziona come previsto.

    grep "string" * mi dà gli errori:

    grep: data: Is a directory
    grep: Desktop: Is a directory
    grep: Documents: Is a directory
    grep: Downloads: Is a directory
    ...
    

Vengono stampati solo gli errori, non ho le righe corrispondenti. Ho provato a utilizzare l'opzione -s , ma senza risultati.

Quindi, le mie domande:

  1. Perché non riesco a utilizzare grep su una directory, come in (1), quando dovrei essere in grado di? Ho visto questo fatto in molti esempi su Internet.
    Modifica : quando dico "usando grep su una directory", intendo "cerca in tutti i file in quella directory escludendo le sue sottodirectory ". Credo che questo sia ciò che fa grep quando passi una directory al suo posto al posto di un file. Sono errato?

  2. Per favore mi dia una spiegazione sul funzionamento di grep che spiegherebbe il comportamento dei comandi in (2).
    Modifica : vorrei essere più specifico. Perché utilizzare i caratteri jolly per specificare più file in cui cercare il lavoro con .bash* e non con * o anche ./* ?

  3. Come posso cercare tutti i file in una directory (e non le sue sottodirectory) usando grep ?

posta John Red 25.05.2016 - 18:07

4 risposte

19

In Bash, un glob non si espanderà in file nascosti, quindi se vuoi cercare tutti i file in una directory, devi specificare i file nascosti .* e non nascosti * .

Per evitare gli errori "È una directory", potresti usare -d skip , ma sul mio sistema ho anche un errore grep: .gvfs: Permission denied , quindi suggerisco di usare -s , che nasconde tutti i messaggi di errore.

Quindi il comando che stai cercando è:

grep -s "string" * .*

Se stai cercando file in un'altra directory:

grep -s "string" /path/to/dir/{*,.*}

Un'altra opzione consiste nell'utilizzare l'opzione di shell dotglob , che renderà un glob includere i file nascosti.

shopt -s dotglob
grep -s "string" *

Per i file in un'altra directory:

grep -s "string" /path/to/dir/*
    
risposta data wjandrea 25.05.2016 - 20:53
7

Hai bisogno dell'opzione -d skip aggiunta.

  1. Grep sta cercando all'interno dei file. Puoi cercare ricorsivamente, come hai detto, se vuoi cercare i file all'interno di una directory.

  2. Per impostazione predefinita, grep leggerà tutti i file e rileva le directory. Poiché per impostazione predefinita non hai definito cosa fare con le directory con l'opzione -d , restituisce l'output dell'errore.

  3. La ricerca all'interno della directory principale potrebbe essere "grep -d skip" stringa "./*

risposta data anonymous2 25.05.2016 - 18:13
6

I vecchi timer lo farebbero probabilmente:

find . -type f -print0 | xargs -0 grep "string"
    
risposta data dathompson 26.05.2016 - 02:25
1

Rifrazione - vuoi dividere i file in un sottodirectory di un livello, ma non ricorrere a tutte le sottodirectory?

grep forthis  *  */*

O se non vuoi i file nella directory corrente

grep forthis  */*

Nota che questo non troverà le directory che iniziano con un punto.

grep forthis  .*/*    */*   

dovrebbe fare quel lavoro.

Sono disponibili anche -maxdepth e -mindepth parametri di restrizione disponibili anche per il comando find .

    
risposta data Criggie 26.05.2016 - 03:42

Leggi altre domande sui tag