2013-08-07 10 views
23

mam jakiś plik jakO używaniu komendy linux "xargs"

love.txt 
loveyou.txt 

w katalogu useful; Chcę skopiować ten plik do katalogu /tmp.

Używam tego polecenia:

find ./useful/ -name "love*" | xargs cp /tmp/ 

ale nie działa, po prostu mówi:

cp: target `./useful/loveyou.txt' is not a directory 

kiedy używam tego polecenia:

find ./useful/ -name "love*" | xargs -i cp {} /tmp/ 

to działa dobrze,

Chcę wiedzieć w hy drugi działa, a więcej o korzystaniu z -i cp {}.

+2

co z 'cp ./useful/love*/tmp /'? – sehe

+2

Ten _will_ działa z GNU cp bez '-i', jak to:' find ./useful/ -name "love *" -print0 | xargs -0 cp -t/tmp' –

+2

... zauważ, że używanie xargs bez '-0' jest niebezpieczne, ponieważ oddziela nazwy plików od nowych linii, ale znak nowej linii jest prawidłowym znakiem w nazwach plików w systemie UNIX. –

Odpowiedz

19

umieszcza słowa pochodzące ze standardowego wejścia na końcu listy argumentów danego polecenia. Dlatego pierwsza forma tworzy

cp /tmp/ ./useful/love.txt ./useful/loveyou.txt 

który nie działa, ponieważ istnieje więcej niż 2 argumenty i ostatni nie jest katalogiem.

Opcja -i mówi xargs przetwarzać jeden plik na raz, chociaż, zastępując {} z jego nazwy, więc jest to równoważne

cp ./useful/love.txt /tmp/ 
cp ./useful/loveyou.txt /tmp/ 

co wyraźnie działa dobrze.

4

Pierwszym przykładem będzie to zrobić:

cp /tmp/ love.txt loveyou.txt 

które nie mogą być wykonane, ponieważ starają się skopiować katalog /tmp i plik love.txt do pliku loveyou.txt.

W drugim przykładzie -i mówi xargs zastąpić każde wystąpienie {} z argumentem, więc będzie to zrobić:

cp love.txt /tmp/ 
cp loveyou.txt /tmp/ 
+2

podczas działania bez -i, polecenie cp zostanie wykonane tylko raz, gdy wszystkie argumenty zostaną przekazane jako lista, nie? na przykład spróbuj za pomocą 'echo' –

+0

@GrahamGriffiths: masz rację. Myślałem o przykładzie 'xargs -n 1'. Poprawię to. –

10

Przy użyciu komendy xargs -i, {} jest podstawiony każdego elementu można znaleźć. Tak więc, w przypadku zarówno „loveyou.txt” i „love.txt”, następujące polecenie zostanie uruchomione:

cp ./useful/loveyou.txt /tmp/ 
cp ./useful/love.txt /tmp/ 

jeśli pominąć {}, wszystkie elementy można znaleźć automatycznie zostanie wstawiony w koniec polecenia, tak, można wykonać polecenie bezsensowny:

cp /tmp/ ./useful/loveyou.txt ./useful/love.txt 
+2

podczas uruchamiania bez -i, polecenie cp zostanie wykonane tylko raz, gdy wszystkie argumenty zostaną przekazane jako lista, nie? na przykład spróbuj za pomocą 'echo' –

+0

@GrahamGriffiths Masz całkowitą rację. Zaktualizowana odpowiedź odpowiednio. Może być zademonstrowany, jeśli zostanie podłączony do 'xargs echo AAA'. –

4

xargs dołącza wartości podawanych w postaci strumienia do końca polecenia - nie uruchomić komendę raz na wartości wejściowej. Jeśli chcesz, aby ta sama komenda była uruchamiana wiele razy - właśnie do tego służy składnia -i cp {}.

Działa to dobrze dla poleceń, które akceptują listę argumentów na końcu (np. Grep) - niestety cp nie jest jednym z nich - uwzględnia argumenty, które przekazujesz jako katalogi do skopiowania, co wyjaśnia "nie jest błąd katalogu.

3
find ./useful/ -name "love*" | xargs cp -t /tmp/ 
+0

-i [replace-str] Ta opcja jest synonimem opcji -Ireplace-str, jeśli podano opcję replace-str, a w przypadku -I {} w przeciwnym razie. Ta opcja jest przestarzała; zamiast tego użyj -I. – user3581131

+1

Dobrze, ale musisz edytować swoje pytanie i umieścić je tam, w przeciwnym razie zablokowane w głosowaniach nie można zmienić. – maraca

Powiązane problemy