Použil jsem to hodně, zlepšení, které se snažím dosáhnout, je vyhnout se názvům souborů echa, které se neshodovaly grep. Lepší způsob, jak to udělat?

 for file in `find . -name "*.py"`; do echo $file; grep something $file; done 

Komentáře

Odpověď

 find . -name "*.py" -exec grep something {} \; -print  

vytiskne název souboru za odpovídajícími řádky.

 find . -name "*.py" -exec grep something /dev/null {} +  

vytiskne název souboru před každý odpovídající řádek (přidáme /dev/null pro případ, že existuje pouze jeden shoda souboru jako grep nevytiskne název souboru, pokud předá pouze jeden soubor, který má být vyhledán. Implementace GNU grep má alternativu -H).

 find . -name "*.py" -exec grep -l something {} +  

vytiskne pouze názvy souborů souborů, které mají alespoň jeden odpovídající řádek.

Chcete-li vytisknout název souboru před odpovídajícími řádky, můžete použít awk místo toho:

 find . -name "*.py" -exec awk " FNR == 1 {filename_printed = 0} /something/ { if (!filename_printed) { print FILENAME filename_printed = 1 } print }" {} +  

Nebo volejte grep dvakrát pro každý soubor – i když by to bylo méně efektivní, protože by spustil alespoň jeden grep příkaz a až dva pro každý soubor (a přečíst obsah souboru dvakrát ):

 find . -name "*.py" -exec grep -l something {} \; \ -exec grep something {} \;  

V každém případě Nechcete smyčku přes výstup find takového a nezapomeňte uvést své proměnné .

Pokud jste chtěli použít smyčku prostředí, s nástroji GNU:

 find . -name "*.py" -exec grep -l --null something {} + | xargs -r0 sh -c " for file do printf "%s\n" "$file" grep something < "$file" done" sh  

(funguje také na FreeBSD a derivátech).

Odpověď

I Pokud používáte GNU grep, můžete použít toto -r nebo --recursive toto jednoduché hledání:

 grep -r --include "*.py" -le "$regexp" ./ # for filenames only grep -r --include "*.py" -He "$regexp" ./ # for filenames on each match  

Potřebujete find, pouze pokud potřebujete pokročilejší predikáty.

Komentáře

  • V závislosti na verzi GNU grep, grep se může, ale nemusí dívat dovnitř symbolických odkazů nebo procházet symbolické odkazy do adresářů. Můžete také najít určité varianty zpracování jiných typů nepravidelných souborů.

Odpovědět

Vy může říct grepu, aby do výstupu zahrnul název souboru. Pokud tedy existuje shoda, zobrazí se na konzole; pokud v souboru není shoda, nebude pro tento soubor vytištěn žádný řádek.

find . -name "*.py" | xargs grep -n -H something 

Z man grep:

-H Always print filename headers with output lines -n, --line-number Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed. This option is ignored if -c, -L, -l, or -q is specified. 

Pokud by vaše soubory mohly mít názvy s mezerami, musíte přepnout kanál, aby jako oddělovač používaly znaky NUL. Celý příkaz bude nyní vypadat takto:

find . -name "*.py" -print0 | xargs -0 grep -n -H something 

Odpovědět

Můžete zkuste něco jako:

find . -name "*.py:" -exec grep -l {} \; 

Tento příkaz exec grep pro každý soubor objevený příkazem find a jeho standardní funkcí příkazu find

Odpověď

Použijte argument -l.

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done 

Další vyhledávací použití by bylo:

for file in $(find . -name "*.py" -exec grep -l something "{}" +); do echo "$file"; grep something $file; done 

Odpověď

Tam jsou grep alternativy, které ve výchozím nastavení zobrazují výsledky ve formátu, který chcete. 2 nejoblíbenější z nich, které znám, jsou ag (aka „stříbrný vyhledávač“) a ack. ag je inzerován jako rychlejší alternativa k ack.

$ ag "^\w+\s*\w+\(" ~/build/i3/src build/i3/src/display_version.c 58:void display_running_version(void) { build/i3/src/load_layout.c 42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = 518:json_content_t json_determine_content(const char *filename) { 575:void tree_append_json(Con *con, const char *filename, char **errormsg) { build/i3/src/x.c 64:CIRCLEQ_HEAD(state_head, con_state) state_head = 67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = 70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = 97:void x_con_init(Con *con, uint16_t depth) { ... 

Tady vás nemohu ukázat, ale výstup je úhledně barevný. Názvy souborů dostávám olivově zelenou, čísla řádků zlatožlutou a odpovídající část v každém řádku krvavě červenou. Barvy jsou přizpůsobitelné.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *