Ik probeer een find
-opdracht uit te voeren voor alle JavaScript-bestanden, maar hoe sluit ik een specifieke map uit?
Hier is de find
code die we gebruiken.
for file in $(find . -name '*.js')
do
java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done
Antwoord 1, autoriteit 100%
Gebruik de schakelaar -prune
. Als u bijvoorbeeld de directory misc
wilt uitsluiten, voegt u gewoon een -path ./misc -prune -o
toe aan uw find-opdracht:
find . -path ./misc -prune -false -o -name '*.txt'
Hier is een voorbeeld met meerdere mappen:
find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -false -o -name '*.txt'
Hier sluiten we ./dir1, ./dir2en ./dir3uit in de huidige directory, aangezien in find
-expressies het is een actie die werkt volgens de criteria -path dir1 -o -path dir2 -o -path dir3
(indien dir1of dir2of dir3), ANDed met type -d
.
Gebruik -name
om de directorynaam op elk niveau uit te sluiten:
find . -type d \( -name node_modules -o -name dir2 -o -path name \) -prune -false -o -name '*.json'
Antwoord 2, autoriteit 98%
Als -prune
niet voor u werkt, zal dit:
find -name "*.js" -not -path "./directory/*"
Voorbehoud:vereist het doorlopen van alle ongewenste mappen.
Antwoord 3, autoriteit 36%
Ik vind het volgende gemakkelijker om over te redeneren dan andere voorgestelde oplossingen:
find build -not \( -path build/external -prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -prune \) -not \( -path build/blog -prune \) -name \*.js
Belangrijke opmerking:de paden die u typt na -path
moeten exact overeenkomen met wat find
zou afdrukken zonder de uitsluiting. Als deze zin verwarrend is, zorg er dan voor dat je volledige paden gebruikt door de opdracht heleals volgt: find /full/path/-not \( -path /full/path/exclude/this-prune \) ...
. Zie opmerking [1] voor een beter begrip.
In \(
en \)
is een uitdrukking die exactbuild/external
zal matchen (zie belangrijke opmerking hierboven), en zal, bij succes, vermijden om iets hieronder te doorkruisen. Dit wordt dan gegroepeerd als een enkele expressie met het escaped haakje, en voorafgegaan door -not
waardoor find
alles overslaat dat overeenkomt met die expressie.
Je zou je kunnen afvragen of het toevoegen van -not
niet alle andere bestanden die verborgen zijn door -prune
weer zullen verschijnen, en het antwoord is nee. De manier waarop -prune
werkt, is dat alles dat, zodra het is bereikt, de bestanden onder die map permanent worden genegeerd.
Dit komt van een daadwerkelijk gebruik, waarbij ik yui-compressor moest aanroepen voor sommige bestanden die door wintersmith waren gegenereerd, maar andere bestanden wegliet die ongewijzigd moeten worden verzonden.
OPMERKING [1] : als u /tmp/foo/bar
wilt uitsluiten en u wilt zoeken zoals deze “find /tmp \(...
“DAN MOET U -path /tmp/foo/bar
SPECIFICEERD. Als u aan de andere kant vindt, vindt u als deze cd /tmp; find . \(...
Dan moet u -path ./foo/bar
.
4, Autoriteit 11%
Dit is de enige die voor mij werkte.
find / -name MyFile ! -path '*/Directory/*'
Zoeken naar “MyFile” exclusief “Directory”.
Geef de nadruk op de sterren *.
5, Autoriteit 5%
Eén optie zou zijn om alle resultaten uit te sluiten die de mapnaam met GRREP bevatten. Bijvoorbeeld:
find . -name '*.js' | grep -v excludeddir
6, Autoriteit 3%
Ik geef de voorkeur aan de -not
notatie … Het is meer leesbaar:
find . -name '*.js' -and -not -path directory
7, Autoriteit 2%
Gebruik de -prune-optie. Dus, zoiets als:
find . -type d -name proc -prune -o -name '*.js'
De ‘-type d -name proc -prune’ zoekt alleen naar mappen met de naam proc om uit te sluiten.
De ‘-o’ is een ‘OF’-operator.
Antwoord 8, autoriteit 2%
-prune
werkt zeker en is het beste antwoord omdat het voorkomt dat u afdaalt naar de map die u wilt uitsluiten. -not -path
die nog steeds de uitgesloten map doorzoekt, maar het resultaat niet afdrukt, wat een probleem kan zijn als de uitgesloten map op het netwerkvolume is gemount of als u geen machtigingen hebt.
Het lastige is dat find
erg kieskeurig is over de volgorde van de argumenten, dus als je ze niet precies goed krijgt, werkt je commando misschien niet. De volgorde van de argumenten is over het algemeen als volgt:
find {path} {options} {action}
{path}
: plaats eerst alle aan het pad gerelateerde argumenten, zoals . -path './dir1' -prune -o
{options}
: ik heb het meeste succes als ik -name, -iname, etc
als laatste optie in deze groep zet. bijv. -type f -iname '*.js'
{action}
: u wilt -print
toevoegen wanneer u -prune
gebruikt
Hier is een werkend voorbeeld:
# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js
# search for *.js, exclude dir1
find . -path './dir1' -prune -o -type f -iname '*.js' -print
# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -prune -o -type f -iname '*.js' -print
Antwoord 9
Dit is de indeling die ik heb gebruikt om sommige paden uit te sluiten:
$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"
Ik heb dit gebruikt om alle bestanden te vinden die niet in “.*”-paden staan:
$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
Antwoord 10
Er zijn veel goede antwoorden, het kostte me alleen wat tijd om te begrijpen waar elk element van de opdracht voor was en de logica erachter.
find . -path ./misc -prune -o -name '*.txt' -print
find begint met het zoeken naar bestanden en mappen in de huidige map, vandaar de find .
.
De optie -o
staat voor een logische OR en scheidt de twee delen van het commando:
[ -path ./misc -prune ] OR [ -name '*.txt' -print ]
Elke map of elk bestand dat nietde ./misc-map is, zal het eerste test -path ./misc
niet doorstaan. Maar ze zullen worden getoetst aan de tweede uitdrukking. Als hun naam overeenkomt met het patroon *.txt
worden ze afgedrukt vanwege de optie -print
.
Als find de map ./misc bereikt, voldoet deze map alleen aan de eerste uitdrukking. Dus de optie -prune
wordt erop toegepast. Het vertelt het find commando om nietdie map te verkennen. Dus elk bestand of elke map in ./misc zal niet eens worden verkend door te vinden, zal niet worden getest tegen het tweede deel van de uitdrukking en zal niet worden afgedrukt.
Antwoord 11
De -path -prune-aanpak werkt ook met jokertekens in het pad. Hier is een find-instructie die de mappen zal vinden voor een git-server die meerdere git-opslagplaatsen bedient, waarbij de interne git-mappen worden weggelaten:
find . -type d \
-not \( -path */objects -prune \) \
-not \( -path */branches -prune \) \
-not \( -path */refs -prune \) \
-not \( -path */logs -prune \) \
-not \( -path */.git -prune \) \
-not \( -path */info -prune \) \
-not \( -path */hooks -prune \)
Antwoord 12
Meerdere mappen uitsluiten:
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)
Om mappen toe te voegen, voegt u -o -path "./dirname/*"
:
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)
Maar misschien moet je een gewone uitdrukkinggebruiken, als er veel mappen zijn om uit te sluiten.
Antwoord 13
een goede truc om te voorkomen dat de gesnoeide mappen worden afgedrukt, is om -print
te gebruiken (werkt ook voor -exec
) na de rechterkant van de -or
na -prune
. Bijvoorbeeld …
find . -path "*/.*" -prune -or -iname "*.j2"
drukt het pad af van alle bestanden onder de huidige map met de extensie `.j2′, waarbij alle verborgen mappen worden overgeslagen. Netjes. Maar het zal ook het volledige pad afdrukken van elke map die wordt overgeslagen, zoals hierboven vermeld. Het volgende echter niet, …
find . -path "*/.*" -prune -or -iname "*.j2" -print
omdat er logischerwijs een verborgen -and
is achter de operator -iname
en vóór de -print. Dit bindt het aan het rechtergedeelte van de -or
-clausule vanwege de booleaanse volgorde van bewerkingen en associativiteit. Maar de documenten zeggen dat er een verborgen -print
is als deze (of een van zijn neven … -print0
, enz.) niet is gespecificeerd. Dus waarom is het linkerdeel van de -or
-afdruk niet? Blijkbaar (en ik begreep dit niet toen ik de man-pagina voor het eerst las), is dat waar als er geen -print
-of -exec
OVERAL is, waarin case, -print wordt logischerwijs rond gestrooid zodat alles wordt afgedrukt. Als zelfs maar EEN print
-achtige bewerking in een clausule wordt uitgedrukt, verdwijnen al die verborgen logische en krijg je alleen wat je opgeeft. Eerlijk gezegd had ik het misschien liever andersom gehad, maar dan zou een find
met alleen beschrijvende operatoren blijkbaar niets uithalen, dus ik denk dat het logisch is zoals het is. Zoals hierboven vermeld, werkt dit allemaal ook met -exec
, dus het volgende geeft een volledige ls -la
-lijst voor elk bestand met de gewenste extensie, maar niet de eerste niveau van elke verborgen map, …
find . -path "*/.*" -prune -or -iname "*.j2" -exec ls -la -- {} +
Voor mij (en anderen in deze thread), wordt de syntaxis find
vrij snel behoorlijk barok, dus ik gooi altijd haakjes tussen haakjes om er zeker van te zijn dat ik weet wat aan wat bindt, dus ik maak meestal een macro voor typbaarheid en vorm al dergelijke uitspraken als …
find . \( \( ... description of stuff to avoid ... \) -prune \) -or \
\( ... description of stuff I want to find ... [ -exec or -print] \)
Het is moeilijk om fout te gaan door de wereld op deze manier in twee delen op te zetten. Ik hoop dat dit helpt, hoewel het onwaarschijnlijk lijkt dat iemand om te lezen aan het 30 + TH-antwoord en stem op, maar men kan hopen. : -)
14
voor een werkoplossing (getest op ubuntu & nbsp; 12.04 (precieze pangolin)) …
find ! -path "dir1" -iname "*.mp3"
Zoeken naar MP3-bestanden in de huidige map en submappen behalve in Dir1-submap.
Gebruik:
find ! -path "dir1" ! -path "dir2" -iname "*.mp3"
… om Dir1 en Dir2
uit te sluiten
15
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'
lijkt hetzelfde te werken als
find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)
en is gemakkelijker om IMO te onthouden.
16
U kunt ook regelmatige uitdrukkingen gebruiken om sommige bestanden / dirs op te nemen / uitsluiten met iets dergelijks:
find . -regextype posix-egrep -regex ".*\.(js|vue|s?css|php|html|json)$" -and -not -regex ".*/(node_modules|vendor)/.*"
Hiermee geeft u alleen alle JS, VUE, CSS, ETC-bestanden, maar exclusief alle bestanden in de node_modules
en vendor
MAPPERS.
17
U kunt gebruik maken van de optie snoeien om dit te bereiken. Net als in bijvoorbeeld:
find ./ -path ./beta/* -prune -o -iname example.com -print
Of de inverse grep “grep -v” optie:
find -iname example.com | grep -v beta
Hier vind je gedetailleerde instructies en voorbeelden in de Linux find commando uit te sluiten directories van het zoeken .
Antwoord 18
find . \( -path '.**/.git' -o -path '.**/.hg' \) -prune -o -name '*.js' -print
Het bovenstaande voorbeeld vindt alle *.js
Bestanden onder de huidige map, exclusief mappen .git
EN .hg
, maakt niet uit hoe Diep deze .git
en .hg
mappen zijn.
Opmerking: dit werkt ook:
find . \( -path '.*/.git' -o -path '.*/.hg' \) -prune -o -name '*.js' -print
Maar ik geef de voorkeur aan de **
notatie voor consistentie met een aantal andere tools die hier uit onderwerp zouden zijn.
19
Geen van eerdere antwoorden is goed op ubuntu.
Probeer dit:
find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"
Ik heb dit gevonden hier
20
Dit is geschikt voor mij op een Mac:
find . -name *.php -or -path "./vendor" -prune -or -path "./app/cache" -prune
Het is uitsluiten vendor
en app/cache
DIR VOOR ZOEKNAAM WELKELIJK MET ZIJN MET php
.
21
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -prune
22
De volgende opdrachten werkt:
find . -path ./.git -prune -o -print
Als u een probleem hebt met het vinden, gebruikt u de -D tree
optie om de expressie-analyse-informatie te bekijken.
find -D tree . -path ./.git -prune -o -print
Of de -D all
, om alle uitvoeringsinformatie te zien.
find -D all . -path ./.git -prune -o -print
Antwoord 23
Als iemand onderzoekt hoe je meerdere paden tegelijk kunt negeren.
U kunt bash-arrays gebruiken (werkt perfect op GNU bash, versie 4.4.20(1)-release)
#!/usr/bin/env bash
# This script helps ignore unnecessary dir paths while using the find command
EXCLUDE_DIRS=(
"! -path /*.git/*"
"! -path /*go/*"
"! -path /*.bundle/*"
"! -path /*.cache/*"
"! -path /*.local/*"
"! -path /*.themes/*"
"! -path /*.config/*"
"! -path /*.codeintel/*"
"! -path /*python2.7/*"
"! -path /*python3.6/*"
"! -path /*__pycache__/*"
)
find $HOME -type f ${EXCLUDE_DIRS[@]}
# if you like fzf
find $HOME -type f ${EXCLUDE_DIRS[@]} | fzf --height 40% --reverse
Ook om de een of andere reden kun je /bin/ directorypaden niet negeren.
Antwoord 24
Ik gebruikte find
om een lijst met bestanden voor xgettext
te leveren, en wilde een specifieke map en de inhoud ervan weglaten. Ik heb veel permutaties van -path
gecombineerd met -prune
geprobeerd, maar ik kon de map die ik weg wilde hebben niet volledig uitsluiten.
Hoewel ik de inhoudvan de map die ik wilde negeren kon negeren, retourneerde find
vervolgens de map zelf als een van de resultaten, waardoor xgettext
crasht als resultaat (accepteert geen mappen; alleen bestanden).
Mijn oplossing was om gewoon grep -v
te gebruiken om de map over te slaan die ik niet in de resultaten wilde hebben:
find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext
Of er een argument is voor find
dat 100% zal werken, kan ik niet met zekerheid zeggen. Het gebruik van grep
was een snelle en gemakkelijke oplossing na wat hoofdpijn.
Antwoord 25
Voor degenen onder u met oudere versies van UNIX die -pathof -not
niet kunnen gebruiken
Getest op SunOS 5.10 bash 3.2 en SunOS 5.11 bash 4.4
find . -type f -name "*" -o -type d -name "*excluded_directory*" -prune -type f
Antwoord 26
hoe-te-gebruiken-prune-option-of-find-in-shis een uitstekend antwoord van Laurence Gonsalvesover hoe -prune
werkt.
En hier is de algemene oplossing:
find /path/to/search \
-type d \
\( -path /path/to/search/exclude_me \
-o \
-name exclude_me_too_anywhere \
\) \
-prune \
-o \
-type f -name '*\.js' -print
Om te voorkomen dat u /path/to/seach/
meerdere keren typt, wikkelt u de find
in een pushd .. popd
-paar.
p>
pushd /path/to/search; \
find . \
-type d \
\( -path ./exclude_me \
-o \
-name exclude_me_too_anywhere \
\) \
-prune \
-o \
-type f -name '*\.js' -print; \
popd
27
Ik heb het bevel hierboven geprobeerd, maar geen van degenen met behulp van “-prune” werkt voor mij.
Uiteindelijk heb ik dit geprobeerd met opdracht hieronder:
find . \( -name "*" \) -prune -a ! -name "directory"