Hoe de find-opdracht in Linux te gebruiken

Linux-opdrachtregelinterface op een rode achtergrond
fatmawati achmad zaenuri/Shutterstock

de Linux find commando is geweldig in het zoeken naar bestanden en mappen. Maar u kunt de resultaten van de zoekopdracht ook doorgeven aan andere programma’s voor verdere verwerking. Wij laten u zien hoe.

Het Linux-zoekcommando

de Linux find commando is krachtig en flexibel. Het kan zoeken naar bestanden en mappen met behulp van een hele reeks verschillende criteria, niet alleen bestandsnamen. Het kan bijvoorbeeld zoeken naar lege bestanden, uitvoerbare bestanden of bestanden die eigendom zijn van een bepaalde gebruiker. Het kan bestanden vinden en weergeven op hun geopende of gewijzigde tijden, je kunt regex-patronen gebruiken, het is standaard recursief en het werkt met pseudo-bestanden zoals named pipes (FIFO-buffers).

Hoe alle zoekopdrachten van Linux te gebruiken

VERWANTHoe alle zoekopdrachten van Linux te gebruiken

Dat is allemaal fantastisch nuttig. de nederige find commando pakt echt wat kracht in. Maar er is een manier om die kracht te benutten en dingen naar een ander niveau te tillen. Als we de uitvoer van de kunnen nemen find commando en het automatisch gebruiken als invoer voor andere commando’s, kunnen we iets laten gebeuren met de bestanden en mappen die voor ons ontdekt worden.

Het principe van het pipen van de uitvoer van de ene opdracht naar een andere opdracht is een kernkenmerk van Unix-afgeleide besturingssystemen. Het ontwerpprincipe om een ​​programma één ding te laten doen en het goed te laten doen, en te verwachten dat de uitvoer de invoer van een ander programma kan zijn – zelfs een nog ongeschreven programma – wordt vaak beschreven als de ‘Unix-filosofie’. En toch zijn er enkele kernhulpprogramma’s, zoals: mkdiraccepteer geen doorgesluisde invoer.

Hoe het xargs-commando op Linux te gebruiken

VERWANTHoe het xargs-commando op Linux te gebruiken

Om deze tekortkoming aan te pakken, xargs commando kan worden gebruikt om doorgesluisde invoer te bundelen en in andere commando’s in te voeren alsof het commandoregelparameters zijn voor dat commando. Hiermee wordt bijna hetzelfde bereikt als eenvoudig leidingwerk. Dat is “bijna hetzelfde” en niet “exact hetzelfde” omdat er onverwachte verschillen kunnen zijn met shell-uitbreidingen en bestandsnaamglobbing.

Zoeken gebruiken met xargs

We kunnen gebruiken find met xargs tot een actie die wordt uitgevoerd op de gevonden bestanden. Dit is een omslachtige manier om dit aan te pakken, maar we kunnen de bestanden die zijn gevonden door find naar binnen xargs die ze vervolgens naar tar om een ​​archiefbestand van die bestanden te maken. We voeren deze opdracht uit in een map die veel PAGE-bestanden van het helpsysteem bevat.

find ./ -name "*.page" -type f -print0 | xargs -0 tar -cvzf page_files.tar.gz

De uitvoer van find via xargs en in tar . doorsturen

De opdracht is opgebouwd uit verschillende elementen.

  • zoek ./ -naam “*.pagina” -type f -print0: De zoekactie start in de huidige map, waarbij op naam wordt gezocht naar bestanden die overeenkomen met de zoekreeks “*.page”. Directory’s worden niet weergegeven omdat we specifiek zeggen dat het alleen naar bestanden moet zoeken, met -type f. De print0 argument vertelt find om witruimte niet te behandelen als het einde van een bestandsnaam. Dit betekent dat bestandsnamen met spaties correct worden verwerkt.
  • xargs -o: De -0 argumenten xargs om witruimte niet te behandelen als het einde van een bestandsnaam.
  • tar -cvzf page_files.tar.gz: Dit is het commando xargs gaat de bestandenlijst voeden van find naar. Het tar-hulpprogramma maakt een archiefbestand aan met de naam “page_files.tar.gz”.

We kunnen gebruiken ls om het archiefbestand te zien dat voor ons is aangemaakt.

ls *.gz

Het archiefbestand gemaakt door de uitvoer van find door xargs en in tar . te leiden

Het archiefbestand wordt voor ons aangemaakt. Om dit te laten werken, moeten alle bestandsnamen worden doorgegeven aan tar massaal, wat is er gebeurd. Alle bestandsnamen zijn getagd op het einde van de tar commando als een zeer lange commandoregel.

U kunt ervoor kiezen om de laatste opdracht op alle bestandsnamen tegelijk uit te voeren of één keer per bestandsnaam aan te roepen. We kunnen het verschil vrij gemakkelijk zien door de uitvoer van xargs naar het hulpprogramma voor het tellen van regels en tekens wc.

Dit commando pijpt alle bestandsnamen in wc onmiddelijk. Effectief, xargs bouwt een lange opdrachtregel voor wc met elk van de bestandsnamen erin.

find . -name "*.page" -type f -print0 | xargs -0 wc

Meerdere bestandsnamen tegelijk naar wc leiden

De regels, woorden en tekens voor elk bestand worden afgedrukt, samen met een totaal voor alle bestanden.

Statistieken voor het tellen van woorden voor veel bestanden, met een totaal voor alle bestanden

Als we gebruik maken van xarg’s -I (replace string) optie en definieer een vervangende string-token—in dit geval ” {}“—het token wordt in de laatste opdracht vervangen door elke bestandsnaam om de beurt. Dit betekent wc wordt herhaaldelijk aangeroepen, één keer voor elk bestand.

find . -name "*.page" -type f -print0 | xargs -0 -I "{}" wc "{}"

Een vervangreeks gebruiken om bestandsnamen één voor één naar een wc te sturen

De output is niet mooi uitgelijnd. Elke aanroep van wc werkt op een enkel bestand dus wc heeft niets om de output mee af te stemmen. Elke regel uitvoer is een onafhankelijke regel tekst.

Uitvoer van meerdere aanroepen van wc

Omdat wc kan alleen een totaal geven als het op meerdere bestanden tegelijk werkt, we krijgen de samenvattende statistieken niet.

De optie find -exec

De find commando heeft een ingebouwde methode om externe programma’s aan te roepen om verdere verwerking uit te voeren op de bestandsnamen die het retourneert. De -exec (uitvoeren) optie heeft een syntaxis die lijkt op, maar verschilt van de xargs opdracht.

find . -name "*.page" -type f -exec wc -c "{}" ;

-exec gebruiken om enkele bestandsnamen naar wc te sturen

Dit telt de woorden in de overeenkomende bestanden. Het commando is opgebouwd uit deze elementen.

  • vinden .: Start het zoeken in de huidige directory. De find commando is standaard recursief, dus er wordt ook in submappen gezocht.
  • -naam “*.pagina”: We zijn op zoek naar bestanden met namen die overeenkomen met de zoekreeks “*.page”.
  • -type f: We zoeken alleen naar bestanden, niet naar mappen.
  • -exec wc: We gaan de . uitvoeren wc commando op de bestandsnamen die overeenkomen met de zoekreeks.
  • -w: Alle opties die u aan de opdracht wilt doorgeven, moeten direct na de opdracht worden geplaatst.
  • “{}”: De tijdelijke aanduiding “{}” vertegenwoordigt elke bestandsnaam en moet het laatste item in de parameterlijst zijn.
  • ;: Een puntkomma “;” wordt gebruikt om het einde van de parameterlijst aan te geven. Het moet worden geëscaped met een backslash “”, zodat de shell het niet interpreteert.

Wanneer we die opdracht uitvoeren, zien we de uitvoer van wc. De -c (byte count) beperkt de uitvoer tot het aantal bytes in elk bestand.

De uitvoer van het gebruik van -exec om veel enkele bestandsnamen naar wc . te sturen

Zoals je ziet is er geen totaal. De wc opdracht wordt eenmaal per bestandsnaam uitgevoerd. Door een plusteken te vervangen “+” voor de afsluitende puntkomma “;” we kunnen veranderen -exec’s gedrag om op alle bestanden tegelijk te werken.

find . -name "*.page" -type f -exec wc -c "{}" +

-exec gebruiken om alle bestandsnamen tegelijk naar wc te sturen

We krijgen de samenvatting van het totaal en netjes getabelleerde resultaten die ons vertellen dat alle bestanden zijn doorgegeven aan wc als één lange opdrachtregel.

Uitvoer van het gebruik van -exec om alle bestandsnamen tegelijk naar wc te sturen

exec Betekent echt exec

De -exec (execute) optie start de opdracht niet door deze in de huidige shell uit te voeren. Het gebruikt de ingebouwde exec van Linux om de opdracht uit te voeren, waarbij het huidige proces – je shell – wordt vervangen door de opdracht. Dus de opdracht die wordt gestart, wordt helemaal niet in een shell uitgevoerd. Zonder shell kun je geen shell-uitbreiding van wildcards krijgen en heb je geen toegang tot aliassen en shell-functies.

Deze computer heeft een gedefinieerde shell-functie genaamd words-only. Dit telt alleen de woorden in een bestand.

function words-only () 
{ 
  wc -w $1
}
Aliassen en Shell-functies maken op Linux

VERWANTAliassen en Shell-functies maken op Linux

Een vreemde functie misschien, “words-only” is veel langer om te typen dan “wc -w”, maar het betekent in ieder geval dat u de opdrachtregelopties voor wc. We kunnen testen wat het als volgt doet:

words-only user_commands.pages

Een shell-functie gebruiken om de woorden in een enkel bestand te tellen

Dat werkt prima met een normale opdrachtregelaanroep. Als we die functie proberen aan te roepen met find’s -exec optie, het zal mislukken.

find . -name "*.page" -type f -exec words-only "{}" ;

Proberen om een ​​shell-functie te gebruiken met -exec

De find commando kan de shell-functie niet vinden, en de -exec actie mislukt.

-exec kan de shell-functie niet vinden, omdat deze niet in een shell draait

Om dit te overwinnen kunnen we hebben find start een Bash-shell en geef de rest van de opdrachtregel door als argumenten aan de shell. We moeten de opdrachtregel tussen dubbele aanhalingstekens plaatsen. Dit betekent dat we moeten ontsnappen aan de dubbele aanhalingstekens rond de “{}” string vervangen.

Voordat we de . kunnen uitvoeren find commando, moeten we onze shell-functie exporteren met de -f (als functie) optie:

export -f words-only
find . -name "*.page" -type f -exec bash -c "words-only "{}"" ;

Zoek gebruiken om een ​​shell te starten om de shell-functie uit te voeren in

Dit loopt zoals verwacht.

De shell-functie die wordt aangeroepen in een nieuwe shell

De bestandsnaam meer dan eens gebruiken

Als u meerdere opdrachten aan elkaar wilt koppelen, kunt u dat doen en kunt u de “{}” vervang string in elke opdracht.

find . -name "*.page" -type f -exec bash -c "basename "{}" && words-only "{}"" ;

Als wij cd een niveau hoger uit de map “pages” en voer dat commando uit, find zal de PAGE-bestanden nog steeds ontdekken omdat het recursief zoekt. De bestandsnaam en het pad worden doorgegeven aan onze words-only functioneren als voorheen. Puur om redenen van het demonstreren van het gebruik van -exec met twee commando’s noemen we ook de basename commando om de naam van het bestand te zien zonder het pad.

Beide basename commando en de words-only shell-functie hebben de bestandsnamen aan hen doorgegeven met behulp van een “{}” string vervangen.

De opdracht basename en de shell-functie met alleen woorden aanroepen vanuit dezelfde -exec-aanroep

Paarden voor cursussen

Er is een CPU-belasting en tijdstraf voor het herhaaldelijk aanroepen van een commando terwijl je het één keer zou kunnen aanroepen en alle bestandsnamen er in één keer aan zou kunnen doorgeven. En als je elke keer een nieuwe shell aanroept om het commando te starten, wordt die overhead erger.

Maar soms heb je – afhankelijk van wat je probeert te bereiken – geen andere optie. Welke methode uw situatie ook vereist, niemand zou verbaasd moeten zijn dat Linux voldoende opties biedt om degene te vinden die aan uw specifieke behoeften voldoet.

Nieuwste artikelen

spot_img

Related Stories

Leave A Reply

Vul alstublieft uw commentaar in!
Vul hier uw naam in