Předpokládejme, že chci najít všechny soubory .txt a vyhledat nějaký řetězec. Udělal bych:

find ./ -type f -name "*.txt" -exec egrep -iH "something" "{}" \; 

Co když chci provést složitější filtrování, například:

egrep something file.txt | egrep somethingelse | egrep other 

Inside find -exec? (nebo podobný)

Pamatujte, že hledám řešení, které bych mohl snadno napsat, když to potřebuji. Vím, že by to bylo možné udělat pomocí několika řádků pomocí shell skriptu, ale to není to, co hledám.

Odpověď

Pokud to musíte udělat zevnitř find, musíte zavolat shell:

find ./ -type f -name "*.txt" -exec sh -c "grep -EiH something "$1" | grep -E somethingelse | grep -E other" sh {} \; 

Mezi další alternativy patří použití xargs:

find ./ -type f -name "*.txt" | xargs -I{} grep -EiH something {} | grep -EiH somethingelse | grep -EiH other 

Nebo , mnohem bezpečnější pro libovolné názvy souborů (za předpokladu, že vaše find podporuje -print0):

find ./ -type f -name "*.txt" -print0 | xargs -0 grep -EiH something {} | grep -Ei somethingelse | grep -Ei other 

Nebo můžete místo toho použít pouze smyčku prostředí:

find ./ -type f -name "*.txt" -print0 | while IFS= read -d "" file; do grep -Ei something "$file" | grep -Ei somethingelse | grep -Ei other done 

Komentáře

  • První je přesně to, co jsem hledal. Extrémně jednoduché a dostatečně malé na psaní v závislosti na mých potřebách. Děkuji.
  • … a xargs lze také použít jako xargs -I {} sh -c '...' sh {}, pokud někdo chtěl (dělá je možné spouštět paralelní úlohy s -P pokud by to někdo chtěl).

Odpovědět

Upravit: Tato odpověď není preferována , ale je zde ponechána pro srovnání a ilustraci potenciálně nebezpečných nástrah. v bash skriptování.


Můžete zadat bash (nebo jiný shell) jako svůj -exec příkaz:

 find -type -f -name "*.txt" -exec bash -c "egrep -iH something "{}" | egrep somethingelse | egrep other" \;  

Jednou z nevýhod tohoto způsobu je, že vytváří více potenciál pro vnořené problémy s citováním, jak se vaše příkazy stávají složitějšími. Pokud se tomu chcete vyhnout, můžete jej rozdělit do for -loop:

 for i in $(find -type -f -name "*.txt"); do if egrep -iH something "$i" | egrep somethingelse | egrep other; then echo "Found something: $i" fi done  

Komentáře

  • První je přesně to, co jsem hledal. Extrémně jednoduché a dostatečně malé na psaní v závislosti na mých potřebách. Děkuji.
  • Tato smyčka for je velmi špatný nápad. Také se jí říká bash pitfall # 1 .
  • Tento "{}" ve vašem prvním příkazu může dokonce vést k vložení kódu. Představte si, že máte ode mě soubory a ' je soubor doslova s názvem " & rm -rf ~ & : ".txt. Naštěstí pro vás -type -f je neplatný, pouze uložil váš domovský adresář. Opravte překlep a zkuste to znovu. 🙂 terdon to udělal správně: find … -exec sh -c '… "$1" …' foo {} \;.
  • děkuji za informaci! Ano, -type -f je překlep, který neustále dělám při používání find, a neudělal jsem ' nevšiml jsem si to v mé odpovědi. Jejda. terdon ' s odpověď je lepší, ale ' to nechám pro srovnávací účely.
  • @terdon: tx pro odkazování na stránku mywiki.wooledge.org. ' Je hezké mít na jednom místě přehledně seskupené GP.

Napsat komentář

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