Hoe de vereiste opdracht te construeren met xargs. Xargs begrijpen. GNU parallel en xargs. Meerdere exemplaren van een opdracht parallel uitvoeren met verschillende argumenten

Bekeken: 717

Er is al veel geschreven over het hulpprogramma xargs - wat kun je nog meer schrijven? Maar als, zoals ze zeggen, dieper graven, blijkt dat in veel publicaties alleen de basis wordt uiteengezet, maar het belangrijkste ontbreekt: het verklaart niet hoe xargs in de echte praktijk kan worden gebruikt. Helaas zijn er maar heel weinig artikelen over de analyse van complexe en niet-triviale toepassingen van deze zeer nuttige tool voor de systeembeheerder. Daarom hebben we ons artikel geschreven en geprobeerd om zoveel mogelijk voorbeelden op te nemen van het gebruik van xargs om verschillende problemen op te lossen.

Eerst zullen we kijken naar het principe van xargs en eenvoudigere voorbeelden analyseren, en dan verder gaan met de analyse van complexe en interessante gevallen.

De basis onthouden

Hoe xargs werkt, kan als volgt worden beschreven: een programma haalt gegevens uit standaardinvoer of uit een bestand, splitst deze op volgens de opgegeven parameters en geeft deze vervolgens als argument door aan een ander programma.

In het algemeen kan de syntaxis van de opdracht xargs als volgt worden weergegeven:

[command_generator_list] | xargs [xargs_options] [opdracht]

Laten we eens kijken hoe het allemaal werkt, gebaseerd op het materiaal van eenvoudige en leerboekvoorbeelden.

Bestanden verwijderen

Een van de meest voorkomende situaties waarin xargs wordt gebruikt, is het verwijderen van bestanden die zijn gevonden met de opdracht find.

Stel je de volgende situatie voor: je hebt een directory die een groot aantal bestanden bevat. Hieruit moet u bestanden van een bepaald type verwijderen (in ons voorbeeld bestanden met de extensie * .sh). Om deze bewerking uit te voeren, moet u de uitvoer van de opdracht find doorgeven aan xargs, en de opdracht -rm wordt toegepast op bestanden met de opgegeven extensie:

$ ls
een.sh een.py twee.sh twee.py

$ ls
een.py twee.py

Merk op dat de bewerking van het verwijderen van bestanden kan worden uitgevoerd zonder xargs en met het commando

$ vinden. -naam "* .sh" -exec rm -rf "()"

De beschreven methode werkt niet als de naam van een van de te verwijderen bestanden een spatie bevat. Een naam die bestaat uit twee woorden, gescheiden door een spatie, wordt niet als één geheel gezien.

Laten we dit illustreren met het volgende voorbeeld:

$ ls
nieuw bestand.sh one.sh one.py two.sh two.py

$ vinden. -naam "* .sh" | xargs rm -rf

$ ls
nieuw bestand.sh one.py two.py

Zoals u kunt zien, is het bestand met een spatie in de naam niet verwijderd.

Om dit probleem op te lossen, gebruikt u de optie print0 voor de opdracht find en de optie -0 voor de opdracht xargs. Het vervangt het standaard scheidingsteken (regeleinde met een null-teken (x0), wat het einde van de opgeslagen tekenreeks betekent:

$ vinden. -naam "* .sh" -print0 | xargs -0 rm -rf

Xargs kan bijvoorbeeld ook helpen om snel alle tijdelijke bestanden met een tmp-extensie te verwijderen:

$ find / tmp -naam "* .tmp" | xargs rm

Bestanden comprimeren

U kunt alle bestanden in de huidige map gzip door de volgende opdracht in te voeren:

$ ls | xargs -p -l gzip

Laten we nog een voorbeeld nemen: alle bestanden met de extensie * .pl comprimeren met tar:

$ vinden. -naam "* .pl" | xargs tar -zcf pl.tar.gz

Bestanden hernoemen

Met xargs kunt u de naam van bestanden in bulk wijzigen. Laten we ons voorstellen dat we een groep bestanden hebben met de extensie * .txt, en dat we deze extensie moeten vervangen door * .sql. Dit kan met xargs en de stream-teksteditor sed:

$ ls | sed -e "p; s / .txt $ /. sql /" | xargs -n2 fmv

Als resultaat van de uitvoering wordt een lijst met hernoemde bestanden op de console weergegeven.

Met xargs kunt u ook extra elementen toevoegen aan bestandsnamen (bijv. datum):

$ ls | xargs -I BESTAND mv () - ()

In plaats daarvan kun je alles vervangen wat je wilt.
De accolades () in dit voorbeeld staan ​​voor "huidig ​​argument" (dat wil zeggen, de huidige bestandsnaam).

Wijzig machtigingen voor mappen en bestanden

U kunt ook xargs gebruiken om het proces van het wijzigen van bestands- en mapmachtigingen voor een specifieke gebruiker of groep te versnellen. Laten we zeggen dat we alle mappen voor root moeten vinden en hun eigenaar moeten vervangen door temp. Deze bewerking wordt uitgevoerd met het commando:

$ vinden. -groep root -print | xargs chown temp

Gebruik de opdracht om alle mappen in de hoofdgroep te vinden en de groep te vervangen door temp:

$ vinden. -groep root -print | xargs chgrp temp

Xargs en zoek: complexe bewerkingen

Meer complexe bewerkingen kunnen worden uitgevoerd met behulp van de opdrachten find en xargs. Zo kunt u bijvoorbeeld tijdelijke bestanden verwijderen die meer dan 7 dagen geleden zijn aangemaakt:

$ find / tmp -type f -naam "*" -mtime +7 -print0 | xargs -0 rm -f

En zo - stop met geweld processen die al meer dan 7 dagen lopen:

$ find / proc -gebruiker mijngebruiker -maxdiepte 1 -type d -mtime +7 -exec basisnaam (); | xargs doden -9

Xargs en knippen

Xargs wordt vaak gebruikt in combinatie met het cut-commando om regels uit tekstbestanden te knippen. Laten we eens kijken naar enkele praktische voorbeelden. Met behulp van de onderstaande opdracht wordt een lijst van alle gebruikers op het systeem weergegeven op de console:

$ knippen -d: -f1

En een commando als

bestand * | grep ASCII | knippen -d ":" -f1 | xargs -p vim

zal bestanden opeenvolgend openen voor bewerking in vim.
Let op de -p optie. Dankzij dit wordt de opdracht interactief uitgevoerd: voordat elk bestand wordt geopend, wordt om bevestiging (y / n) gevraagd.

Ter afsluiting zullen we nog een complexer en interessanter voorbeeld geven - recursief zoeken naar bestanden van de grootste grootte in een bepaalde map:

$ vinden. -type f -printf "s% pn" | sorteer -n | knippen -b22- | tr "n" "

xargs- hulpprogramma voor het vormen van een lijst met argumenten en het uitvoeren van opdrachten. Dat wil zeggen, met xargs kun je elk commando met argumenten aanroepen. De opdracht xargs heeft twee componenten. Eerst moet u de bestanden specificeren die u interesseren. Ten tweede moet u de opdracht of het script specificeren dat u op elk van deze bestanden wilt toepassen.

xargs - splitst de invoerstroom in argumenten en geeft hun uitvoering door aan een willekeurig commando (standaard echo). Leest van standaard invoer of pijp.

Wijzen voor het verwerken van xargs van inkomende gegevens

    Standaard wordt elk witruimteteken beschouwd als het argumentscheidingsteken: spatie, tab, verticale tab of regelinvoer. Maar net als bij de shell, kunt u "" of \ gebruiken om het splitsen van argumenten te voorkomen.

    De modus ingeschakeld door de parameter -L. Bijna identiek aan de vorige, behalve dat xargs onthoudt welk argument op welke regel staat. Bovendien, als een regel eindigt met een spatie of tab, wordt de volgende regel beschouwd als een voortzetting van de huidige.

    Lijn bij lijn. Inbegrepen bij gebruik van de -I of -0 optie. In dit geval wordt de hele regel beschouwd als één geheel getal, ondanks de spaties en tabs erin. Voor -I is het einde van de regel "\ n" en voor -0, het teken "\ 0"

    Voorbeeld: Zoeken / home / user1 naar alle bestanden waarvan de naam eindigt op ".txt" en deze naar een andere map kopiëren. zoek / home / gebruiker1 -naam "* .txt" | xargs cp -av --target-directory = / home / back-up / --parents

    Zoek het voorkomen van de zin logon home in alle bestanden in de map / etc / samba. $ zoek / etc / samba | xargs grep -ni "aanmelden thuis"

    Bestandslijst verwijderen. De paden naar het bestand worden regel voor regel geschreven in het bestand delfiles.txt xargs rm< delfiles.txt

Er is al veel geschreven over het hulpprogramma xargs - wat kun je nog meer schrijven? Maar als, zoals ze zeggen, dieper graven, blijkt dat in veel publicaties alleen de basis wordt uiteengezet, maar het belangrijkste ontbreekt: het verklaart niet hoe xargs in de echte praktijk kan worden gebruikt. Helaas zijn er maar heel weinig artikelen over de analyse van complexe en niet-triviale toepassingen van deze zeer nuttige tool voor de systeembeheerder. Daarom hebben we ons artikel geschreven en geprobeerd om zoveel mogelijk voorbeelden op te nemen van het gebruik van xargs om verschillende problemen op te lossen.

Eerst zullen we kijken naar het principe van xargs en eenvoudigere voorbeelden analyseren, en dan verder gaan met de analyse van complexe en interessante gevallen.

De basis onthouden

Hoe xargs werkt, kan als volgt worden beschreven: een programma haalt gegevens uit standaardinvoer of uit een bestand, splitst deze op volgens de opgegeven parameters en geeft deze vervolgens als argument door aan een ander programma.

In het algemeen kan de syntaxis van de opdracht xargs als volgt worden weergegeven:

[command_generator_list] | xargs [xargs_options] [opdracht]
Laten we eens kijken hoe het allemaal werkt, gebaseerd op het materiaal van eenvoudige en leerboekvoorbeelden.

Bestanden verwijderen

Een van de meest voorkomende situaties waarin xargs wordt gebruikt, is het verwijderen van bestanden die zijn gevonden met de opdracht find.

Stel je de volgende situatie voor: je hebt een directory die een groot aantal bestanden bevat. Hieruit moet u bestanden van een bepaald type verwijderen (in ons voorbeeld bestanden met de extensie * .sh). Om deze bewerking uit te voeren, moet u de uitvoer van de opdracht find doorgeven aan xargs, en de opdracht -rm wordt toegepast op bestanden met de opgegeven extensie:

$ ls one.sh one.py two.sh two.py $ vinden. -naam "* .sh" | xargs rm -rf $ ls one.py two.py

Merk op dat de bewerking van het verwijderen van bestanden kan worden uitgevoerd zonder xargs en met het commando

$ vinden. -naam "* .sh" -exec rm -rf "()" \

De beschreven methode werkt niet als de naam van een van de te verwijderen bestanden een spatie bevat. Een naam die bestaat uit twee woorden, gescheiden door een spatie, wordt niet als één geheel gezien.

Laten we dit illustreren met het volgende voorbeeld:

$ ls nieuw bestand.sh one.sh one.py two.sh two.py $ find. -naam "* .sh" | xargs rm -rf $ ls nieuw bestand.sh one.py two.py

Zoals u kunt zien, is het bestand met een spatie in de naam niet verwijderd.

Om dit probleem op te lossen, gebruikt u de optie print0 voor de opdracht find en de optie -0 voor de opdracht xargs. Het vervangt het standaard scheidingsteken (regelinvoer met een null-teken (\ x0), wat het einde van de opgeslagen tekenreeks betekent:

$ vinden. -naam "* .sh" -print0 | xargs -0 rm -rf

Xargs kan bijvoorbeeld ook helpen om snel alle tijdelijke bestanden met een tmp-extensie te verwijderen:

$ find / tmp -naam "* .tmp" | xargs rm

Bestanden comprimeren

U kunt alle bestanden in de huidige map gzip door de volgende opdracht in te voeren:

$ ls | xargs -p -l gzip

Laten we nog een voorbeeld nemen: alle bestanden met de extensie * .pl comprimeren met tar:

$ vinden. -naam "* .pl" | xargs tar -zcf pl.tar.gz

Bestanden hernoemen

Met xargs kunt u de naam van bestanden in bulk wijzigen. Laten we ons voorstellen dat we een groep bestanden hebben met de extensie * .txt, en dat we deze extensie moeten vervangen door * .sql. Dit kan met xargs en de stream-teksteditor sed:

$ ls | sed -e "p; s / .txt $ /. sql /" | xargs -n2 fmv

Als resultaat van de uitvoering wordt een lijst met hernoemde bestanden op de console weergegeven.

Met xargs kunt u ook extra elementen toevoegen aan bestandsnamen (bijv. datum):

$ ls | xargs -I BESTAND mv ()<...>-{}

In plaats van<..>je kunt alles vervangen wat je wilt.
De accolades () in dit voorbeeld staan ​​voor "huidig ​​argument" (dat wil zeggen, de huidige bestandsnaam).

Wijzig machtigingen voor mappen en bestanden

U kunt ook xargs gebruiken om het proces van het wijzigen van bestands- en mapmachtigingen voor een specifieke gebruiker of groep te versnellen. Laten we zeggen dat we alle mappen voor root moeten vinden en hun eigenaar moeten vervangen door temp. Deze bewerking wordt uitgevoerd met het commando:

$ vinden. -groep root -print | xargs chown temp

Gebruik de opdracht om alle mappen in de hoofdgroep te vinden en de groep te vervangen door temp:

$ vinden. -groep root -print | xargs chgrp temp

Xargs en zoek: complexe bewerkingen

Meer complexe bewerkingen kunnen worden uitgevoerd met behulp van de opdrachten find en xargs. Zo kunt u bijvoorbeeld tijdelijke bestanden verwijderen die meer dan 7 dagen geleden zijn aangemaakt:

$ find / tmp -type f -naam "*" -mtime +7 -print0 | xargs -0 rm -f

En zo - stop met geweld processen die al meer dan 7 dagen lopen:

$ find / proc -user myuser -maxdepth 1 -type d -mtime +7 -exec basename () \; | xargs doden -9

Xargs en knippen

Xargs wordt vaak gebruikt in combinatie met het cut-commando om regels uit tekstbestanden te knippen. Laten we eens kijken naar enkele praktische voorbeelden. Met behulp van de onderstaande opdracht wordt een lijst van alle gebruikers op het systeem weergegeven op de console:

$ knippen -d: -f1< /etc/passwd | sort | xargs echo

En een commando als

Bestand * | grep ASCII | knippen -d ":" -f1 | xargs -p vim
zal bestanden opeenvolgend openen voor bewerking in vim.
Let op de -p optie. Dankzij dit wordt de opdracht interactief uitgevoerd: voordat elk bestand wordt geopend, wordt om bevestiging (y / n) gevraagd.

Ter afsluiting zullen we nog een complexer en interessanter voorbeeld geven - recursief zoeken naar bestanden van de grootste grootte in een bepaalde map:

$ vinden. -type f -printf "% 20s% p \ n" | sorteer -n | knippen -b22- | tr "\ n" "\ 000" | xargs -0 ls -laSr

Processen parallel uitvoeren

Xargs wordt vaak gebruikt om meerdere processen parallel te laten lopen. Zo kunt u in tar.gz bijvoorbeeld meerdere mappen tegelijk comprimeren:

$ echo map1 map2 map3 | xargs -P 3 -I NAAM tar czf NAAM.tar.gz NAAM

In dit voorbeeld wordt de schakeloptie -P gebruikt. Het geeft het maximale aantal processen aan dat gelijktijdig kan worden uitgevoerd. Stel we hebben 10 argumenten als invoer. Als we het xargs-commando geven met de -P 3-optie, dan zullen 3 instanties van het commando na xargs worden uitgevoerd, met elk van deze argumenten.

U kunt ook veel bestanden parallel van internet downloaden met xargs:

In het gegeven voorbeeld worden alle grafische bestanden met de extensie jpg gedownload vanaf het opgegeven adres; de schakeloptie -P geeft aan dat u 10 bestanden tegelijk wilt downloaden.

Voorlopige resultaten

Laten we de voorlopige resultaten samenvatten en enkele regels formuleren voor het werken met xargs.

  1. Xargs werkt niet met bestanden die een spatie in hun naam hebben. De -0 optie wordt gebruikt om dit probleem op te lossen met het xargs commando. De spatie in de bestandsnaam kan ook als volgt worden omzeild:
    $ xargs -I BESTAND mijn_commando "BESTAND"
  2. De opdracht xargs accepteert opdrachten van standaardinvoer, gescheiden door spaties of nieuwe regels. U kunt dubbele of enkele aanhalingstekens gebruiken om deze opdrachten te groeperen. U kunt ook een scheidingsteken opgeven met de optie -d;
  3. Als er helemaal geen argumenten aan het xargs-commando worden doorgegeven, is de standaardwaarde /bin/echo;
  4. In veel gevallen kan de opdracht xargs worden vervangen door een for-lus. Bijvoorbeeld het commando
    $ vinden. -type f -en -iname "* .deb" | xargs -n 1 dpkg -I
    volledig gelijk aan een cyclus
    $ voor bestand in `find. -type f -en -iname "* .deb" `; doe dpkg -I "$ bestand"; gedaan

Niet-triviale voorbeelden

We herinnerden ons de basis, keken naar typische gebruiksscenario's ... Laten we nu verder gaan met complexere en niet-triviale voorbeelden. Sommige hebben we zelf bedacht, terwijl we aan alledaagse taken werkten, en sommige zijn overgenomen van de site http://www.commandlinefu.com handige tips).

IP-adressen uit de lijst weren

Om IP-adressen uit de lijst te weren, moet u ze toevoegen aan IP-tabellen met de DROP-regel. Deze bewerking wordt uitgevoerd met het commando:

$ kat bad_ip_list | xargs -I IP iptables -A INPUT -s IP -j DROP
U kunt een complexere operatie uitvoeren en alle adressen door AS verbieden:

$ / usr / bin / whois -H -h whois.ripe.net -T route -i oorsprong AS<номер>| egrep "^ route" | awk "(print $ 2)" | xargs -I NET iptables -A INPUT -s NET -j DROP

Het URL-formaat wijzigen

U kunt een URL zoals "http% 3A% 2F% 2Fwww.google.com" naar "www, google.com" converteren met het commando:

Echo "http% 3A% 2F% 2Fwww.google.com" | sed -e "s /% \ (\) / \\\\\ x \ 1 / g" | xargs echo -e

Een wachtwoord van 10 tekens genereren

U kunt een sterk wachtwoord genereren met een opdracht van het formulier:

$ tr -dc A-Za-z0-9_< /dev/urandom | head -c 10 | xargs

U kunt wachtwoorden genereren zonder de hulp van xargs: hier is een gespecialiseerd hulpprogramma pwgen voor. Enkele andere manieren om wachtwoorden te genereren worden ook beschreven.

Zoeken naar binaire bestanden die zijn geïnstalleerd zonder dpkg . te gebruiken

Een dergelijke operatie kan nodig zijn als bijvoorbeeld een machine het slachtoffer is geworden van een hackeraanval en er kwaadaardige software op is geïnstalleerd. Het volgende commando zal helpen te identificeren welke programma's de aanvallers hebben geïnstalleerd (het zoekt naar actieve "binaries" die geïnstalleerd zijn zonder gebruik te maken van de dpkg-pakketbeheerder):

$ сat /var/lib/dpkg/info/*.list> / tmp / listin; ls / proc / * / exe | xargs -l readlink | grep -xvFf / tmp / lijst; rm / tmp / lijst

Verouderde kernelpakketten verwijderen

$ dpkg -l linux- * | awk "/ ^ ii / (druk $ 2)" | grep -v -e `uname -r | knippen -f1,2 -d "-" `| grep -e | xargs sudo apt-get -y purge

Het probleem van het verwijderen van oude kernels is al besproken op Habré - zie (op dezelfde link vind je curieuze voorbeelden van commando's).

Converteer het script naar een string

Soms is het nodig om een ​​groot script om te zetten in één regel. Je kunt het als volgt doen: Tags toevoegen

Ik werd onlangs geïnspireerd om dit bericht te schrijven nadat ik situaties tegenkwam waarin ik verschillende bestanden van een project moest bewerken en sommige woorden door andere moest vervangen. Ik deed het vroeger via Kladblok ++(CTRL + H), maar het is goed als we weten in welk bestand we het woord moeten vervangen, en of er duizenden van deze bestanden zijn. Dus ik wil u 3 basishulpmiddelen van het systeem voorstellen: UNIX vandaag: grep, xargs, en sed.

Je hebt ze misschien al eerder gehoord en weet al hoe je ze moet gebruiken, maar je zult zeker niets nieuws leren. Maar als je de basis van het gebruik van deze tools wilt leren, lees dan verder.

Grep

Grep is een Unix-commandobasis voor het zoeken naar zinnen uit zowel de standaardstream als bestanden. Grep retourneert informatie over de bestanden die uw zin bevatten en wat informatie over waar ze zijn. Hier is een voorbeeld van een standaard manier om Grep te gebruiken:

Grep "footer" index.html

Laten we nu enkele zoekopties toevoegen:

  • l- Negeert geval voor vergelijkingen.
  • N- Geeft voor elke regel zijn nummer in het bestand.
  • B- Geeft het kolomnummer in het gevonden bestand.
grep -i -n -b "voettekst" index.html

Zoek nu naar hele woorden:

  • met wie- Zoekt naar hele woorden. Bijvoorbeeld, in een normale zoekopdracht naar de string tekst grep kan het woord textarea vinden... En als deze sleutel wordt gebruikt, worden alleen regels met het woord tekst gevonden.
grep -w "tekst" index.html

Zoeken door een bestand is prima, maar het is beter als we recursief naar bestanden kunnen zoeken in het hele project.

  • R- Recursief zoeken naar bestanden uit de huidige map.
  • ik- Retourneert alleen bestandsnamen die de gewenste waarde bevatten.
grep -r -l "voettekst" ./

Laten we nu proberen bestanden weer te geven die niet de gewenste waarde bevatten.

  • L- Geeft de namen weer van bestanden die niet de gewenste waarde hebben.
grep -r -L -i "voettekst" ./

Ook moeten we heel vaak zoeken naar een bepaalde waarde in specifieke bestandstypen.

  • –Include = "PATROON"- Zoek in bestanden voor een bepaald patroon
grep -r --include = "*.html" -l "footer" ./

Zoek naar bestanden die beginnen met index en eindigen met .php

Grep -r --include = "index * .php" -l "footer" ./

Laten we nu het resultaat van ons werk naar een bestand overbrengen.

Grep -r -l "voettekst" ./> out.txt

Xargs

Deze geweldige opdracht werkt op een trailer, haalt gegevens uit standaardinvoer of uit een bestand, splitst deze op volgens de opgegeven parameters en geeft deze vervolgens als argument door aan een ander programma. Xargs wordt uitgevoerd totdat de gegevens van de stream zijn uitgeput. Laten we nu enkele eenvoudige voorbeelden bekijken.

Verdeel de standaardstroom in argumenten.

  • -N- We geven het aantal geretourneerde argumenten aan.
echo 1 2 3 4 | xargs -n 1

Laten we nu het scheidingsteken voor argumenten instellen.

  • -NS- Geeft een scheidingsteken aan voor het weergeven van argumenten.
echo "1-2-3-4" | xargs -d "-" -n 1

Hier is een interessanter voorbeeld waarbij xargs wordt gebruikt om bestanden over te brengen die moeten worden verwijderd.

Vind. -naam "* .txt" | xargs rm -rf

Het hele punt van het gebruik van xargs is om de invoerargumenten te splitsen zodat ze kunnen worden doorgegeven aan andere programma's.

sed

Sed is een streaming-editor die tekst uit een standaardstream of een tekstbestand haalt, enkele bewerkingen op de regels uitvoert en het resultaat vervolgens afdrukt naar standaarduitvoer of naar een bestand. Meestal wordt sed in scripts gebruikt bij pipelining, samen met andere opdrachten en hulpprogramma's.

We maken een eenvoudige vervanging van regels uit het tekst.txt-bestand en slaan het op in het out.txt-bestand.

Sed "s / tekst / test / g" text.txt> out.txt

Laten we nu alle wijzigingen in het huidige bestand opslaan.

  • l- om wijzigingen in het huidige bestand te schrijven.
sed -i "s / tekst / test / g" text.txt

Alles met elkaar combineren

Door deze drie commando's te combineren, die gemeenschappelijk zijn voor alle Unix-systemen, kunnen we een redelijk krachtig script maken voor het vervangen van tekst. De meeste actie komt van het gebruik van het sed-commando, maar andere commando's zijn handig voor het bouwen van de query. Laten we nu eens kijken naar een voorbeeld van het gebruik van alle drie de sweep-programma's:

Grep -r -l "foo" ./ | xargs sed -i "s / foo / bar / g"

Zo konden we alles vervangen foo Aan bar met een eenvoudige combinatie van deze programma's.

Nu we de basis hebben geleerd van hoe geweldige tools zoals grep, xargs en sed werken. We zullen meer geavanceerde scripts kunnen schrijven voor onze taken.


Auteur: Joshua Reed
Publicatiedatum: 25 september 2014
Vertaling: A. Krivoshey
Datum van overdracht: april 2015

Ben je ooit in een situatie terechtgekomen waarin je dezelfde opdracht vaak achter elkaar moet uitvoeren? Als dat zo is, dan begrijp je hoe saai en ineffectief het is. En het goede nieuws is dat op Unix gebaseerde besturingssystemen een geweldig xargs-commando hebben om dit probleem op te lossen.Met dit commando kunt u zeer efficiënt werken met een groot aantal bestanden, waardoor u tijd en moeite bespaart. In dit artikel leest u hoe u dit doet.
De opdracht xargs heeft twee componenten. Eerst moet u de bestanden specificeren die u interesseren. Ten tweede moet u de opdracht of het script specificeren dat u op elk van deze bestanden wilt toepassen.
In deze zelfstudie bekijken we drie scenario's voor het gebruik van de opdracht xargs om bestanden te verwerken die zich in verschillende mappen bevinden:

1. Tellen van het aantal regels in alle bestanden.
2. Voer de eerste regel van de opgegeven bestanden uit.
3. Elk bestand verwerken met behulp van het opgegeven script.

Overweeg een map met de naam xargstest (de mapstructuur kan worden weergegeven met behulp van de opdracht tree met de opties -i en -f, die de resultaten weergeven zonder inspringing en met het volledige padvoorvoegsel voor elk bestand):

$ boom -if xargstest /

De xargstest-directory, zijn subdirectories en bestanden zullen verder in onze voorbeelden worden gebruikt.

Scenario 1: Het aantal regels in alle bestanden tellen

Zoals eerder vermeld, is het eerste onderdeel van het xargs-commando de lijst met bestanden waarop het commando werkt. U kunt de opdracht find gebruiken om deze bestanden te identificeren en op te sommen. Optie -naam "bestand ??" laat zien dat we alleen geïnteresseerd zijn in bestanden waarvan de naam begint met "file", waarna er nog twee tekens in de naam staan. De zoekopdracht wordt uitgevoerd in de xargstest-directory en de zoekopdracht wordt recursief uitgevoerd, dat wil zeggen in alle xargstest-subdirectories (indien aanwezig).

$ zoek xargstest / -name "bestand ??" xargstest / dir3 / bestand3B xargstest / dir3 / bestand3A xargstest / dir1 / bestand1A xargstest / dir1 / bestand1B xargstest / dir2 / bestand2B xargstest / dir2 / bestand2A

We kunnen de zoekresultaten omleiden naar de sorteeropdracht om op naam te sorteren:

$ zoek xargstest / -name "bestand ??" | sort xargstest / dir1 / file1A xargstest / dir1 / file1B xargstest / dir2 / file2A xargstest / dir2 / file2B xargstest / dir3 / file3A xargstest / dir3 / file3B

Nu hebben we een tweede component nodig, de opdracht die we willen uitvoeren. Om het aantal regels in elk bestand te tellen, gebruiken we het wc-commando met de optie -l (het aantal regels wordt weergegeven aan het begin van elke uitvoerregel):

$ zoek xargstest / -name "bestand ??" | sorteren | xargs wc -l 1 xargstest / dir1 / file1A 2 xargstest / dir1 / file1B 3 xargstest / dir2 / file2A 4 xargstest / dir2 / file2B 5 xargstest / dir3 / file3A 6 xargstest / dir3 / file3B 21 totaal

Je kunt zien dat in plaats van handmatig het wc -l commando op elk van deze bestanden uit te voeren, xargs je in staat stelt deze bewerking uit te voeren met een enkel commando. U kunt eenvoudig verschillende bewerkingen uitvoeren met honderden bestanden.

Scenario 2: voer de eerste regel van elk gegeven bestand uit

Nu je een algemeen begrip hebt van het gebruik van het xargs-commando, heb je volledige vrijheid bij het kiezen van het uit te voeren commando. Soms hoeft u slechts een selectie van bestanden te verwerken, maar niet allemaal in een bepaalde map. In dit geval moet u de opdracht find gebruiken met de optie -name om de vereiste bestanden te selecteren en ze om te leiden naar de opdracht xargs. Als u bijvoorbeeld de eerste regel wilt afdrukken van alle bestanden die eindigen op "B", gebruikt u de volgende combinatie van find, xargs en head (head -n1 drukt de eerste regel van het bestand af):

$ zoek xargstest / -name "bestand? B" | sorteren | xargs head -n1 ==> xargstest / dir1 / file1B<== one ==>xargstest / dir2 / file2B<== one ==>xargstest / dir3 / file3B<== one

U kunt zien dat alleen bestanden waarvan de naam op "B" eindigt, worden verwerkt, de rest wordt genegeerd.

Scenario 3: Elk bestand verwerken met een script

Ten slotte kunt u uw eigen script hebben (bijvoorbeeld geschreven in Bash, Python of Perl) om de bestanden te verwerken. Vervang gewoon de naam door de wc- en head-commando's in het vorige voorbeeld.

$ zoek xargstest / -name "bestand ??" | xargs mijnscript.sh

Het myscript.sh-script moet zo worden geschreven dat het een bestandsnaam als argument gebruikt en dat bestand verwerkt. De bovenstaande opdracht past dit script toe op elk bestand dat met de opdracht find wordt gevonden.

Merk op dat in de bovenstaande voorbeelden bestandsnamen geen spaties bevatten. Over het algemeen kun je zeggen dat het leven op Linux veel prettiger is als je geen spaties in bestandsnamen gebruikt. Als u bestanden moet verwerken waarvan de namen spaties bevatten, werkt de bovenstaande opdracht niet. Het moet een beetje worden aangepast door de optie "-print0" toe te voegen aan de opdracht find (die de volledige naam afdrukt gevolgd door een null-teken naar stdout) en de optie -0 aan de opdracht xargs (die het null-teken interpreteert op de einde van de regel) zoals hieronder weergegeven:

$ zoek xargstest / -name "bestand *" -print0 | xargs -0 mijnscript.sh

Merk op dat het argument voor de -name optie is veranderd in "file *", wat betekent dat alle bestanden met namen beginnend met "file" en eindigend met een willekeurig karakter.

Conclusie

Na het lezen van deze tutorial, ken je de mogelijkheden van het xargs-commando en hoe je ze in je werk kunt gebruiken. Binnenkort ben je veel minder tijd kwijt aan repetitieve taken. Als u meer wilt weten over alle opties en mogelijkheden van het xargs-commando, typt u gewoon een terminal in.