Zde je jeden způsob, jak to můžete udělat...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
pro mě toto řešení nefungovalo na příkazu exec s find, opravdu nevím proč, takže moje řešení je
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
Vysvětlení: stejné jako sampson-chen one s dodatky
-prune - ignoruje cestu zpracování ...
-o - Pokud se nenajde žádná shoda, vytiskněte výsledky (ořízněte adresáře a vytiskněte zbývající výsledky)
18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3: 0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4: 0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5: 0.0% -- replaced with ./e/5.gz
./e/a: 0.0% -- replaced with ./e/a.gz
./e/b: 0.0% -- replaced with ./e/b.gz
Zde je návod, jak to můžete zadat pomocí find
:
find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"
Vysvětlení:
find .
- Spustit hledání z aktuálního pracovního adresáře (ve výchozím nastavení rekurzivně)-type f
- Zadejte nafind
že ve výsledcích chcete pouze soubory-name "*_peaks.bed"
- Hledejte soubory s názvem končícím na_peaks.bed
! -path "./tmp/*"
- Vyloučit všechny výsledky, jejichž cesta začíná./tmp/
! -path "./scripts/*"
- Vyloučit také všechny výsledky, jejichž cesta začíná./scripts/
Testování řešení:
$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"
./d/4
./c/3
./e/a
./e/b
./e/5
Byli jste docela blízko, -name
volba bere v úvahu pouze základní název, kde je -path
bere v úvahu celou cestu =)
Použijte
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
nebo
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
nebo
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
Pořadí je důležité. Vyhodnocuje se zleva doprava. Vždy začněte vyloučením cesty.
Vysvětlení
Nepoužívejte -not
(nebo !
) pro vyloučení celého adresáře. Použijte -prune
.Jak je vysvětleno v návodu:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
a v příručce GNU najít:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
Pokud použijete -not -path "./pathname"
,Find vyhodnotí výraz pro každý uzel pod "./pathname"
.
vyhledávací výrazy jsou pouze vyhodnocením podmínky.
\( \)
- operace skupin (můžete použít-path "./tmp" -prune -o -path "./scripts" -prune -o
, ale je podrobnější).-path "./script" -prune
- pokud-path
vrátí true a je to adresář, vrátí true pro tento adresář a ne sestoupit do něj.-path "./script" ! -prune
- vyhodnotí se jako(-path "./script") AND (! -prune)
. Vrátí "vždy pravdivé" z prune na vždy nepravdivé. Vyhne se tisku"./script"
jako zápas.-path "./script" -prune -false
- od-prune
vždy vrátí hodnotu true, můžete ji sledovat pomocí-false
udělat totéž než!
.-o
- NEBO operátor. Pokud mezi dvěma výrazy není zadán žádný operátor, použije se jako výchozí operátor AND.
Proto \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
je rozšířena na:
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
Tisk je zde důležitý, protože bez něj je rozšířen na:
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
se přidává pomocí find - to je důvod, proč ho většinou nemusíte přidávat do výrazu. A od -prune
vrátí true, vypíše "./script" a "./tmp".
V ostatních to není nutné, protože jsme přešli na -prune
vždy vrátit hodnotu false.
Tip:Můžete použít find -D opt expr 2>&1 1>/dev/null
vidět, jak je optimalizován a rozšířen,
find -D search expr 2>&1 1>/dev/null
abyste viděli, která cesta je zaškrtnuta.