GNU/Linux >> Znalost Linux >  >> Linux

Použijte příkaz find, ale vylučte soubory ve dvou adresářích

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 na find ž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.


Linux
  1. Jak zjistit nejlepší adresáře a soubory (místo na disku) v Linuxu

  2. Najít největší soubory nebo adresáře?

  3. Vyloučit seznam adresářů z Unixového příkazu Najít?

  1. Jak používat Linuxový příkaz find k hledání souborů

  2. Jak vyloučit adresář v find . příkaz

  3. Jak najít / vypsat všechny jedinečné soubory ve dvou adresářích?

  1. Najděte soubory a adresáře v Linuxu pomocí příkazu find

  2. Jak používat příkaz Grep k vyhledání textu v souborech

  3. Jak použít příkaz find k odstranění souborů odpovídajících vzoru?