Hur man använder kommandot xargs på Linux

Behöver du sätta ihop några Linux-kommandon, men ett av dem accepterar inte piped input? xargs kan ta utdata från ett kommando och skicka det till ett annat kommando som parametrar.

Alla standard Linux-verktyg har tre dataströmmar förknippas med dem. De är standardinmatningsströmmen (stdin), standardutgångsströmmen (stdout) och standardfelströmmen (stderr).

Dessa strömmar arbetar med text. Vi skickar input (stdin) till ett kommando med hjälp av text, och svaret (stdout) skrivs till terminalfönstret som text. Felmeddelanden skrivs också till terminalfönstret som text (stderr).

En av de fantastiska funktionerna i Linux och Unix-liknande operativsystem är möjligheten att överföra stdout-utgången från ett kommando till stdin-ingången för ett andra kommando. Det första kommandot bryr sig inte om att dess utdata inte går till ett terminalfönster, och det andra kommandot bryr sig inte om att dess inmatning inte kommer från ett tangentbord.

Även om alla Linux-kommandon har de tre standardströmmarna, accepterar inte alla ett annat kommandos stdout som indata till deras stdin. Det betyder att du inte kan röra input till dem.

xargs är ett kommando för att bygga exekveringspipelines med standarddataströmmar. Genom att använda xargs kan vi få kommandon som echo, rm och mkdir att acceptera standardinmatning som argument.

Kommandot xargs

xargs kommer att acceptera piped input. Den kan också acceptera indata från en fil. xargs använder den ingången som parametrar för de kommandon vi har sagt att den ska fungera med. Om vi ​​inte säger åt xargs att arbeta med ett specifikt kommando kommer det som standard att använda eko.

Vi kan använda det för att visa hur xargs alltid kommer att generera en enda rad med utdata, även från multi-line input.

Om vi ​​använder alternativet -1 (lista en fil per rad) med ls får vi en enda kolumn med filnamn.

ls -1 ./*.sh

Detta listar skalskriptfilerna i den aktuella katalogen.

Vi får en enda kolumn som förväntat. Om vi ​​rör det genom xargs vad får vi?

ls -1 ./*.sh | xargs

Utdata skrivs till terminalfönstret, som en lång ström av text.

Det är denna förmåga som låter oss xargs mata in parametrar till andra kommandon.

Använda xargs med wc

Vi kan använda xargs för att enkelt få wc att räkna ord, tecken och rader i flera filer.

ls *.page | xargs wc

Det här är vad som händer:

ls listar *.page-filerna och skickar listan till xargs.
xargs skickar filnamnen till wc.
wc behandlar filnamnen som om den hade tagit emot dem som kommandoradsparametrar.

Statistiken för varje fil visas tillsammans med en totalsumma.

Använda xargs med bekräftelse

Vi kan använda alternativet -p (interaktivt) för att få xargs att uppmana oss att bekräfta att vi är glada att det fortsätter.

Om vi ​​skickar en rad filnamn att röra, genom xargs, kommer beröring skapa filerna för oss.

echo 'one two three' | xargs -p touch

Kommandot som kommer att köras visas och xargs väntar på att vi ska svara genom att skriva ”y” eller ”Y”, eller ”n” eller ”N” och trycka på Enter.

Om du bara trycker på Enter behandlas det som ”n”. Kommandot körs endast om du skriver ”y” eller ”Y”.

Vi tryckte på ”y” och tryckte på Enter. Vi kan använda ls för att kontrollera att filerna har skapats.

ls one two three

Använda xargs med flera kommandon

Vi kan använda flera kommandon med xargs genom att använda alternativet -I (initial argument).

Det här alternativet definierar en ”ersätt-sträng.” Varhelst token för ersätt-strängen visas på kommandoraden, infogas värdena som tillhandahölls till xargs.

Låt oss använda trädkommandot för att titta på underkatalogerna från den aktuella katalogen. Alternativet -d (katalog) gör att trädet ignorerar filer och bara rapporterar om kataloger.

tree -d

Det finns en enda underkatalog som heter ”bilder”.

I en fil som heter ”directories.txt” har vi namnen på några kataloger som vi vill ha skapat. Vi kan titta på dess innehåll med hjälp av cat.

cat directories.txt

Vi kommer att använda detta som indata för xargs. Kommandot vi kommer till är detta:

cat directories.txt | xargs -I % sh -c 'echo %; mkdir %'

Detta delas upp så här:

cat directories.txt |: Detta skjuter in innehållet i filen directories.txt (alla nya katalognamn) till xargs.
xargs -I %: Detta definierar en ”ersätt-sträng” med token ”%”.
sh -c: Detta startar ett nytt subshell. -c (kommandot) säger åt skalet att läsa kommandon från kommandoraden.
’eko %; mkdir %’: var och en av ”%”-tokenerna kommer att ersättas av katalognamnen som skickas av xargs. Echo-kommandot kommer att skriva ut katalognamnet; kommandot mkdir kommer att skapa katalogen.

Katalogen listas en efter en.

Vi kan använda tree en gång till för att verifiera att katalogerna har skapats.

tree -d

Kopiera filer till flera platser

Vi kan använda xargs för att tillåta oss att kopiera filer till flera platser med ett enda kommando.

Vi kommer att överföra namnen på två kataloger till xargs som indataparametrar. Vi kommer att säga åt xargs att bara skicka en av dessa parametrar åt gången till kommandot den arbetar med.

I det här fallet är kommandot cp. Så effekten är att anropa cp två gånger, varje gång med en av de två katalogerna som kommandoradsparameter. Xargs-parametern som tillåter detta att hända är alternativet -n (max antal). Vi kommer att ställa in detta till en.

Vi använder också alternativet -v (verbose) med cp så att det rapporterar vad som händer.

echo ~/Backups/ ~/Documents/page-files/ | xargs -n 1 cp -v ./*.page

Filerna kopieras till de två katalogerna, en katalog i taget. cp rapporterar varje filkopieringsåtgärd så att vi kan se att de äger rum.

Ta bort filer i kapslade kataloger

Om filnamn har mellanslag och konstiga tecken i dem – som nyradstecken – kommer xargs inte att kunna tolka dem korrekt. Vi kan lösa det problemet genom att använda alternativet -0 (nullterminator). Detta talar om för xargs att använda noll-tecknet som den sista avgränsaren för filnamn.

Vi kommer att använda find i det här exemplet. hitta har sitt eget alternativ för hantera blanksteg och konstiga tecken i filnamn. Det är alternativet -print0 (fullständigt namn, nolltecken).

find . -name "*.png" -type f -print0 | xargs -0 rm -v -rf "{}"

Detta delas upp så här:

hitta . -name ”*.png”: find kommer att söka från den aktuella katalogen ”.” för objekt med namn som matchar ”*.png” som är filer (typ -f).
-print0: namn kommer att avslutas med ett nolltecken, och mellanslag och konstiga tecken kommer att tillgodoses.
xargs -0: xargs kommer också att betrakta filnamn som noll-terminerade, och mellanslag och konstiga tecken kommer inte att orsaka problem.
rm -v -rf ”{}”: rm kommer att vara utförlig och rapportera vad som händer (-v). Det kommer att vara rekursivt (-r) och titta igenom kapslade underkataloger, och tar bort filer utan att fråga (-f). ”{}” ersätts av varje filnamn.

hitta .  -namn

Alla underkataloger genomsöks och filerna som matchar sökmönstret raderas.

Ta bort kapslade kataloger

Låt oss säga att vi vill ta bort en uppsättning kapslade underkataloger. träd låter oss se dem.

tree -d

find . -name "level_one" -type d printo | xargs -o rm -v -rf "{}"

Detta kommando kommer att använda find för att söka rekursivt inom den aktuella katalogen. Sökmålet är en katalog som heter ”level_one”. Katalognamnen skickas genom xargs till rm.

hitta .  -namn

De enda betydande ändringarna mellan det här kommandot och det föregående kommandot är att söktermen är namnet på den översta katalogen, och -typ d säger till find att leta efter kataloger, inte filer.

Namnet på varje katalog skrivs ut när den tas bort. Vi kan kolla med träd:

tree -d

Alla kapslade underkataloger tas bort.

Ta bort alla filer, utom en filtyp

Vi kan använda find, xargs och rm för att radera alla filer förutom en typ vi vill behålla. Det är lite kontraintuitivt, men vi anger namnet på filtypen vi vill behålla, inte namnet på de vi vill ta bort.

Alternativet -not säger åt find att returnera namnen på de filer som inte matchar sökmönstret. Vi använder alternativet -I (initial argument) med xargs en gång till. Den här gången är den ersättningssträngstoken vi definierar ”{}”. Detta kommer att bete sig exakt på samma sätt som den ersättningssträngstoken vi genererade tidigare, som råkade vara en ”%”.

find . -type f -not - name "*.sh" -print0 | xargs -0 -I {} rm -v {}

hitta .  -typ f -inte - namn

Vi kan kolla med ls. De enda filer som finns kvar i katalogen är de som matchade ”*.sh”-sökmönstret.

ls -l

Skapa en arkivfil med Xargs

Vi kan använda find för att söka efter filer och skicka dem genom xargs till tar, för att skapa en arkivfil.

Vi ska söka i den aktuella katalogen. Sökmönstret är ”*.page” så vi kommer att leta efter ”.page”-filer.

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

hitta ./ - namn

Filerna listas som förväntat när arkivfilen skapas.

Dataförmedlaren

Ibland behöver man lite byggnadsställningar när man staplar ihop saker. xargs överbryggar klyftan mellan kommandon som kan pumpa ut information och kommandon som inte är byggda för att ta in den.

Både xargs och fynd har ett stort antal alternativ. Du uppmuntras att kolla in deras man-sidor för att lära dig mer.