HP-UX ***** B.11.23 U ia64 **** licencja nieograniczonego użytkownika
find . -type d -name *log* | xargs ls -la
daje mi nazwy katalogów (te, które zawierają log
nazwę katalogu), a następnie wszystkie pliki w tym katalogu.
Katalogi /var/opt/SID/application_a/log/
, /var/opt/SID/application_b/log/
, /var/opt/SID/application_c/log/
i tak dalej zawierać pliki dziennika.
Chcę, aby polecenie zawierało tylko dwa najnowsze pliki dziennika ls
, których zwykle używam ls -latr | tail -2
.
Wynik musi być mniej więcej taki ...
/var/opt/SID/application_a/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
/var/opt/SID/application_b/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
/var/opt/SID/application_c/log/
-rw-rw-rw- 1 user1 user1 59698 Jun 11 2013 log1
-rw-rw-rw- 1 user1 user1 59698 Jun 10 2013 log2
find . -type d -name *log* | xargs ls -la | tail -2
nie daje mi powyższego wyniku. Dostaję listę ostatnich dwóch plików
find . -type d -name *log* | xargs ls -la
poleceń.
Czy mogę przesyłać polecenia po potoku xargs
? Jak inaczej zapytać, aby uzyskać wynikową listę plików w powyższym formacie?
find . -type d -name *log* | xargs sh -c "ls -ltr | tail -10"
daje mi listę dziesięciu nazw katalogów w bieżącym katalogu, który akurat jest /var/opt/SID
i nie jest to również to, czego chcę.
*log*
przeciwnym razie powłoka go rozszerzy.sh -c
spodziewa się , że nazwa polecenia (parametr 0) będzie drugim argumentem, więc powinieneś zawsze to robićfind . -type d -name *log* | xargs sh -c "ls -ltr | tail -10" lstail
(zwróć uwagęlstail
na końcu, który będzie służył jak$0
dla utworzonej powłoki). W przeciwnym razie pierwszy z wyników wypełni tę rolę i pozostanie niewykorzystany.Odpowiedzi:
Jesteś prawie na miejscu. W swoim ostatnim poleceniu możesz użyć,
-I
aby wykonaćls
poprawnieWięc z
znajdziesz
echo
katalog znaleziony przezfind
, a następnie zróbls | tail
to.źródło
xargs -n 1 sh -c 'echo $0'
echo $0
była pomocna (i bardziej zrozumiała)-print0
,xargs -0
i uciec{}
w cudzysłów wewnątrz tejsh
komendy:find . -type d -name "*log*" -print0 | xargs -0 -I {} sh -c "echo \"{}\";ls -la \"{}\" | tail -2"
GNU Parallel sprawia, że tego rodzaju zadania są łatwe:
Jeśli nie chcesz wykonywać pełnej instalacji GNU Parallel, możesz wykonać minimalną instalację: http://git.savannah.gnu.org/cgit/parallel.git/tree/README
źródło
Oprócz fredtantini i jako ogólne wyjaśnienie (ponieważ dokumenty są nieco mylące):
xargs -I {}
Podejmie „{}” znaki ze standardowego wejścia i zastąpić je cokolwiek pochodzi z rury. Oznacza to, że możesz faktycznie zastąpić{}
dowolną kombinacją znaków (być może w celu lepszego dopasowania preferowanego smaku programowania). Na przykład :xargs -I % sh -c "echo %"
. Jeśli zawsze używaszxargs -I {}
, możesz go zastąpić,xargs -i
ponieważ jest to skrót.Polecenie
sh -c
bash / shell odczyta następne polecenie z łańcucha, a nie ze standardowego wejścia. Więc pisaniesh -c "echo something"
jest równoważneecho something
.xargs -I {} sh -c "echo {}"
Odczyta wejście utworzony zsh -c
co jestecho {}
. Ponieważ powiedziałeś, aby zastąpić{}
argumentami, które otrzymałeś z potoku, tak się stanie.Możesz to łatwo przetestować nawet bez instalacji potokowej, po prostu wpisz powyższe polecenie w terminalu. Cokolwiek napiszesz później, zostanie wyświetlone na terminalu (Ctrl-D, aby wyjść).
W
ls -la {}
poleceniu to samo dzieje się ponownie.{}
Otrzymuje z treści polecenia wstępnego rury.źródło