xargs --replace / -I dla pojedynczych argumentów

10

Próbuję użyć xargs, aby uruchomić polecenie dla każdego dostarczonego argumentu, ale niestety flaga --replace / -I nie działa poprawnie po połączeniu z -n. Wygląda na to, że {} rozwinie się do pełnej listy argumentów odczytanych ze standardowego wejścia, niezależnie od opcji -n.

Niestety, wszystkie przykłady w sieci wydają się dotyczyć poleceń (mv, cp, rm), które przyjmą wiele argumentów w przypadku rozszerzenia {}.

Na przykład podczas uruchamiania:

echo a b c d | xargs -n 1 -I {} echo derp {}

Dane wyjściowe to:

derp a b c d

Ale spodziewałem się:

derp a
derp b
derp c
derp d

Jednak uruchomienie go bez opcji -I {} daje oczekiwany wynik:

echo a b c d | xargs -n 1 echo derp
derp a
derp b
derp c
derp d

Czy jest jakiś sposób na osiągnięcie tego za pomocą xargs? Moim ostatecznym zamiarem jest użycie go do uruchamiania wielu sesji ssh, takich jak

echo server{1..90} | xargs -n 1 -P 0 -I {} ssh {} 'echo $SOME_HOST_INFO'

Biegnę xargs (GNU findutils) 4.4.2na RHEL 6.3.

André Fernandes
źródło
2
Co ciekawe, działa tak, jak chcesz z BSD xargs, ale nie GNU xargs.
slhck
1
man xargsna -I: Also, unquoted blanks do not terminate input items; instead the separator is the newline character. Implies -x and -L 1.Więc zachowuje się zgodnie z przeznaczeniem.
Daniel Beck
@ André, skoro Twoim celem jest równoległe uruchamianie taksów, czy spojrzałeś na GNU równolegle? Świetnie sobie radzi. Oświadczenie: Pakuję to dla Debiana.
rbrito
GNU równolegle wydawało się dobrym zamiennikiem, ale niestety nie mogę go zainstalować na tym konkretnym hoście.
André Fernandes,
@ AndréFernandes Czy możesz opracować, jeśli twój powód nie jest objęty przez oletange.blogspot.dk/2013/04/why-not-install-gnu-parallel.html
Ole Tange

Odpowiedzi:

5

Możesz wyświetlać nowe wiersze, aby osiągnąć oczekiwany wynik. W twoim przypadku z rozszerzeniem serwera byłoby to:

$ echo -e server{1..4}"\n" | xargs -I{} echo derp {}
derp server1
derp server2
derp server3
derp server4
ahilsend
źródło
Pomysł nowego wiersza działa wokół problemu (ale nie z twoim dokładnym przykładem): serwer echo {1..4} | tr '' '\ n' | xargs -I {} echo derp {} derp server1 derp server2 derp server3 derp server4
André Fernandes
Przepraszamy, przetestowałem to z zsh... Naprawiłem moją odpowiedź. echopotrzebuje -eopcji.
ahilsend
2

Możesz skorzystać z dodatkowej rury takiej jak ta,

echo a b c d | xargs -n1 | xargs -I{} echo derp {}
derp a
derp b
derp c
derp d

Pośrednie użycie xargs „echa” każdej litery „abcd” indywidualnie z powodu opcji „-n1”. To umieszcza każdą literę w jej własnej linii, tak jak to,

echo a b c d | xargs -n1
a
b
c
d 

Ważne jest, aby zrozumieć, kiedy używasz -I (zamiana łańcucha), xargs implikuje -L, który wykonuje polecenie narzędzia (w twoim przypadku echo) raz na linię. Nie można również użyć opcji -n z opcją -L, ponieważ wzajemnie się wykluczają.

synergy77
źródło