it-swarm-eu.dev

Kdy je potřeba xargs?

Příkaz xargs mě vždy zaměňuje. Existuje pro to obecné pravidlo?

Vezměme si dva příklady níže:

$ \ls | grep Cases | less

tiskne soubory, které odpovídají 'Případům', ale změna příkazu na touch bude vyžadovat xargs:

$ \ls | grep Cases | touch
touch: missing file operand
Try `touch --help' for more information.

$ \ls | grep Cases | xargs touch
136
Zaid

Rozdíl je v tom, jaká data cílový program přijímá.

Pokud používáte pouze potrubí, přijímá data na STDIN (standardní vstupní proud) jako hrubou hromadu dat, která je možné třídit po jednom řádku najednou. Některé programy však jejich příkazy standardně nepřijímají, očekávají, že budou uvedeny v argumentech příkazu. Například touch vezme název souboru jako parametr na příkazovém řádku, jako například: touch file1.txt.

Pokud máte program, který vydává názvy souborů standardně a chcete je používat jako argumentytouch, musíte použít xargs který čte data toku STDIN a převádí každý řádek na argumenty oddělené od místa na příkaz.

Tyto dvě věci jsou rovnocenné:

# touch file1.txt
# echo file1.txt | xargs touch

Nepoužívejte xargs, pokud přesně nevíte, co dělá a proč je to potřeba. Často se stává, že existuje lepší způsob, jak tuto práci provést, než použít k vynucení konverze použití xargs. Proces převodu je také plný potenciálních úskalí, jako je únik a Word expanze atd.

146
Caleb

Abychom mohli rozšířit již poskytnuté odpovědi, může xargs udělat jednu skvělou věc, která se v dnešním vícebarevném a distribuovaném výpočetním prostředí stává stále důležitější: může paralelně zpracovávat úlohy.

Například:

$ find . -type f -name '*.wav' -print0 |xargs -0 -P 3 -n 1 flac -V8

bude kódovat * .wav => * .flac, pomocí tří procesů najednou (-P 3).

73
amphetamachine

xargs je zvláště užitečné, když máte na stdin seznam filepathů a chcete s nimi něco udělat. Například:

$ git ls-files "*.tex" | xargs -n 1 sed -i "s/color/colour/g"

Podívejme se na tento krok za krokem:

$ git ls-files "*.tex"
tex/ch1/intro.tex
tex/ch1/motivation.tex
....

Jinými slovy, naším vstupem je seznam cest, k nimž chceme něco udělat.

Chcete-li zjistit, co xargs dělá s těmito cestami, je pěkným trikem přidání echo před váš příkaz, například:

$ git ls-files "*.tex" | xargs -n 1 echo sed -i "s/color/colour/g"
sed -i "s/color/colour/g" tex/ch1/intro.tex
sed -i "s/color/colour/g" tex/ch1/motivation.tex
....

Argument -n 1 Způsobí, že xargs změní každý řádek na vlastní příkaz. Příkaz sed -i "s/color/colour/g" Nahradí všechny výskyty color s colour pro určený soubor.

Pamatujte, že to funguje, pouze pokud nemáte v cestě žádné mezery. Pokud tak učiníte, měli byste použít null zakončené cesty jako vstup do xargs předáním příznaku -0. Příkladem použití by bylo:

$ git ls-files -z "*.tex" | xargs -0 -n 1 sed -i "s/color/colour/g"

Což dělá to samé, co jsme popsali výše, ale také funguje, pokud jedna z cest obsahuje mezeru.

Toto funguje s jakýmkoli příkazem, který produkuje názvy souborů jako výstup, například find nebo locate. Pokud jej však použijete v úložišti git se spoustou souborů, může být efektivnější použít jej s git grep -l Namísto git ls-files, Například:

$ git grep -l "color" "*.tex" | xargs -n 1 sed -i "s/color/colour/g"

Příkaz git grep -l "color" "*.tex" Poskytne seznam souborů „* .tex“ obsahující frázi „color“.

24
Sverre Rabbelier

Váš první argument ukazuje rozdíl docela dobře.

\ls | grep Cases | less umožňuje procházet seznam jmen souborů vytvořených ls a grep. Nezáleží na tom, že se jedná o názvy souborů, jsou to jen nějaké texty.

\ls | grep Cases | xargs less umožňuje procházet soubory, jejichž jména jsou vytvořena první částí příkazu. xargs vezme seznam názvů souborů jako vstup a příkaz na příkazový řádek a spustí příkaz s názvy souborů na příkazovém řádku jeho.

Při zvažování použití xargs mějte na paměti, že očekává vstup formátovaný zvláštním způsobem: oddělovač bílé, s \, ' a " používá pro citace (neobvyklým způsobem, protože \ není zvláštní uvozovky). xargs použijte, pouze pokud vaše názvy souborů neobsahují mezeru nebo \'".

Ve vašem příkladu nemusíte vůbec používat xargs, protože find bude dělat přesně a bezpečně to, co chcete dělat.

Přesně to, co chcete pomocí find, je:

find -maxdepth 1 -name '*Cases*' -exec touch {} +

V tomto příkladu znamená -maxdepth 1 Pouze vyhledávání v aktuálním adresáři, nespadají do žádných podadresářů; Ve výchozím nastavení bude vyhledávání vypadat ve všech podadresářích (což je často to, co chcete), pokud jej neomezíte pomocí maxdepth. {} Je název souboru, který bude nahrazen na svém místě a + Je jedním ze dvou značek na konci příkazu, druhý je ;. Rozdíl mezi nimi je v tom, že ; Znamená vykonat příkaz na každém souboru jeden po druhém, zatímco + Znamená provést příkaz na všech souborech najednou. Mějte však na paměti, že vaše Shell se pravděpodobně pokusí interpretovat samotný ;, Takže jej budete muset uniknout buď \; Nebo ';'. Ano, find má řadu malých nepříjemností, jako je tato, ale její síla je víc, než se to podaří.

Obě find a xargs se obtížně naučí. Chcete-li se naučit xargs, zkuste použít volbu -p Nebo --interactive, Která vám ukáže příkaz, který se má provést, a vyzve vás, zda jej chcete spustit.

Podobně s find můžete použít -ok Namísto -exec K zobrazení výzvy, zda chcete příkaz spustit.

Jsou však případy, kdy find nebude schopen dělat vše, co chcete, a to je místo, kam se dostane xargs. Příkaz -exec Přijme pouze jednu instanci Objeví se {}, Takže pokud byste dostali chybu s find -type f -exec cp {} {}.bak \;, Mohli byste to místo toho udělat takto: find -type f -print0 | xargs -0 -l1 -IX cp X X.bak

Další informace o Run Commands naleznete v GNU Findutils manual .

Také jsem zmínil, že find bezpečně dělá, co chcete, protože když pracujete se soubory, narazíte na mezery a další znaky, které způsobí problémy s xargs, pokud nepoužijete -0 Nebo --null, Spolu s něčím, co generuje vstupní položky zakončené nulovým znakem místo mezery.

4
aculich

xargs (spolu s find, sort, du, uniq, Perl a několika dalšími) přijímá přepínač příkazového řádku, který říká: „STDIN má seznam souborů oddělených NUL (0x00) bajt“. To usnadňuje manipulaci se jmény souborů s mezerami a dalšími vtipnými postavami v nich. Názvy souborů neobsahují NUL.

1
waltinator