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
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.
xargs
lze také použít jakoxargs -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).