Różnica polega na tym, jakie dane akceptuje program docelowy.
Jeśli użyjesz tylko potoku, odbiera on dane w STDIN (standardowy strumień wejściowy) jako nieprzetworzony stos danych, który może sortować według jednej linii na raz. Jednak niektóre programy nie akceptują swoich poleceń w standardzie, oczekują, że zostaną one zapisane w argumentach polecenia. Na przykład touch
przyjmuje nazwę pliku jako parametr w linii poleceń tak: touch file1.txt
.
Jeśli masz program, który wyprowadza nazwy plików na standardowe wyjście i chcą wykorzystać je jako argumenty do touch
, trzeba użyć xargs
która odczytuje dane strumienia stdin i konwertuje każdy wiersz w przestrzeni oddzielonych argumenty polecenia.
Te dwie rzeczy są równoważne:
# touch file1.txt
# echo file1.txt | xargs touch
Nie używaj, xargs
chyba że wiesz dokładnie, co robi i dlaczego jest potrzebny. Dość często zdarza się, że jest lepszy sposób na wykonanie zadania niż xargs
wymuszenie konwersji. Proces konwersji jest również obarczony potencjalnymi pułapkami, takimi jak ucieczka i rozwijanie słów itp.
xargs
i$(...)
), xargs jest znacznie bezpieczniejszy niż zastępowanie poleceń. I nie mogę sobie przypomnieć, że kiedykolwiek natrafiłem na prawidłową nazwę pliku z nową linią. Czy problemy z ucieczką i rozszerzaniem słów nie są związane z zastępowaniem poleceń, a nie xargsem?xargs -0
), co jest przydatne w połączeniu zfind -print0
.xargs
wywołuje program przez powłokę z argumentami oddzielonymi spacjami, czy faktycznie konstruuje listę argumentów wewnętrznie (np. Do użycia zexecv
/execp
)?-d \n
, chociaż BSarg xargs (OSX i in.) Nie wydaje się obsługiwać tej opcji.Aby rozwinąć już udzielone odpowiedzi,
xargs
można zrobić jedną fajną rzecz, która staje się coraz ważniejsza w dzisiejszym środowisku przetwarzania wielordzeniowego i rozproszonego: może równolegle przetwarzać zadania.Na przykład:
zakoduje * .wav => * .flac, używając trzech procesów jednocześnie (
-P 3
).źródło
-exec
Parametr nie będzie przetwarzał zadań równoległych.-0
argument przemawiający zaxargs
uznaniemNULL
znaku za separator elementu wejściowego.find -print0
wyprowadza elementy rozdzielane wartościami NULL. Jest to świetna praktyka w przypadku nazw plików, które mogą zawierać spacje, cudzysłowy lub inne znaki specjalne.xargs jest szczególnie użyteczny, gdy masz listę ścieżek plików na stdin i chcesz coś z nimi zrobić. Na przykład:
Przeanalizujmy to krok po kroku:
Innymi słowy, nasze dane wejściowe to lista ścieżek, z którymi chcemy coś zrobić.
Aby dowiedzieć się, co xargs robi z tymi ścieżkami, fajną sztuczką jest dodanie
echo
przed poleceniem:-n 1
Argumentem uczyni xargs kolei każdą linię do polecenia własnych.sed -i "s/color/colour/g"
Polecenie zastąpi wszystkie wystąpieniacolor
zecolour
dla określonego pliku.Pamiętaj, że działa to tylko wtedy, gdy nie masz spacji na ścieżkach. Jeśli to zrobisz, powinieneś użyć ścieżek zakończonych zerem jako danych wejściowych do xargs, przekazując
-0
flagę. Przykładem użycia może być:Co robi to samo, co opisano powyżej, ale działa również, jeśli na jednej ze ścieżek jest spacja.
Działa to z każdym poleceniem, które generuje nazwy plików jako dane wyjściowe, takie jak
find
lublocate
. Jeśli jednak zdarzy się, że użyjesz go w repozytorium git z dużą ilością plików, bardziej efektywne może być użycie gogit grep -l
zamiastgit ls-files
, na przykład:git grep -l "color" "*.tex"
Komenda da listę plików „* .tex” zawierających frazę „kolor”.źródło
Twój pierwszy argument dość dobrze ilustruje różnicę.
\ls | grep Cases | less
pozwala przeglądać listę nazw plików utworzonych przezls
igrep
. Nie ma znaczenia, że są to nazwy plików, to tylko tekst.\ls | grep Cases | xargs less
pozwala przeglądać pliki, których nazwy są tworzone przez pierwszą część polecenia.xargs
pobiera listę nazw plików jako dane wejściowe i polecenia w linii poleceń, a uruchamia polecenie z nazwami plików w swojej linii komend.Kiedy rozważa wykorzystanie
xargs
, należy pamiętać, że oczekuje wejścia sformatowane w dziwny sposób: rozdzielany białe znaki, z\
,'
i"
służy do cytowania (w nietypowy sposób, bo\
to nie specjalne cytaty wewnątrz). Używaj tylkoxargs
wtedy, gdy twoje nazwy plików nie zawierają białych znaków lub\'"
.źródło
xargs
ma-0, --null
opcję obejścia problemu ze spacjami (jest bardzo prawdopodobne, że dowiedziałem się o tym od ciebie :), więc zakładam, że masz na myślixarg
wywołanie braku opcji , ale jestem zaskoczony odniesieniem do cytatów. Czy masz link lub przykład na ten temat? .. (ps.| xargs less
to przydatna „sztuczka” +1 .. dzięki ..W twoim przykładzie nie musisz wcale używać,
xargs
ponieważfind
zrobi dokładnie i bezpiecznie to, co chcesz zrobić.Dokładnie to, czego chcesz użyć
find
to:W tym przykładzie
-maxdepth 1
oznacza tylko wyszukiwanie w bieżącym katalogu, nie schodź do żadnych podkatalogów; domyślnie find będzie szukał we wszystkich podkatalogach (co często jest tym, czego chcesz), chyba że ograniczysz go z maxdepth. Jest{}
to nazwa pliku, który zostanie zastąpiony na swoim miejscu i+
jest jednym z dwóch znaczników końca polecenia, drugim jest;
. Różnica między nimi polega na tym,;
że polecenie wykonuje się na każdym pliku pojedynczo, natomiast+
polecenie wykonuje się na wszystkich plikach jednocześnie. Należy jednak pamiętać, że powłoka będzie prawdopodobnie próbować interpretować;
siebie, więc trzeba będzie uciec z albo\;
albo';'
. Tak,find
ma wiele takich niedogodności, ale jego moc nadrabia to.Zarówno
find
ixargs
są trudne, aby dowiedzieć się w pierwszej kolejności. Aby pomóc w nauce,xargs
spróbuj użyć opcji-p
lub--interactive
, która pokaże polecenie, które zamierza wykonać, i podpowie, czy chcesz je uruchomić.Podobnie
find
możesz użyć-ok
zamiast,-exec
aby zapytać, czy chcesz uruchomić polecenie.Są jednak chwile, kiedy
find
nie będzie w stanie zrobić wszystkiego, co chcesz, i to jest miejscexargs
.-exec
Polecenie zaakceptuje tylko jedno wystąpienie{}
, więc jeśli wystąpi błądfind -type f -exec cp {} {}.bak \;
, możesz zamiast tego zrobić tak :find -type f -print0 | xargs -0 -l1 -IX cp X X.bak
Możesz dowiedzieć się więcej o poleceniach uruchamiania w podręczniku GNU Findutils .
Wspomniałem również, że
find
bezpiecznie robi to, co chcesz, ponieważ podczas pracy z plikami napotkasz spacje i inne znaki, które będą powodować problemy,xargs
chyba że użyjesz opcji-0
lub--null
wraz z czymś, co generuje elementy wejściowe zakończone znakiem null białych znaków.źródło
'
lub"
mogą być problematyczne, podczasfind
gdy bez problemu poradzą sobie z tymi sprawami.xargs
(wraz zfind
,sort
,du
,uniq
,perl
i kilka innych) akceptuje przełącznik wiersza polecenia, aby powiedzieć „STDIN zawiera listę plików, oddzielone NUL (0x00) bajt”. Ułatwia to obsługę nazw plików ze spacjami i innymi zabawnymi postaciami. Nazwy plików nie zawierają wartości NUL.źródło