2012-11-05 21 views
6

Chciałbym przekazać listę wyjściową elementów polecenia jako parametr innego polecenia. Znalazłem kilka innych stron:Dane wyjściowe polecenia Linux jako parametr innego polecenia

ale wydają się być bardziej skomplikowana.

Po prostu chciałbym skopiować plik do każdego wyniku połączenia z poleceniem Linux find.

Co jest nie tak tutaj ?:

find . -name myFile 2>&1 | cp /home/myuser/myFile $1 

Dzięki

Odpowiedz

16

To jest to, co chcesz:

find . -name myFile -exec cp /home/myuser/myFile {} ';' 

Podział/wyjaśnienie tego:

  • find: wywoływanie polecenia find
  • .: Rozpocznij wyszukiwanie od bieżącego katalogu roboczego.
  • Ponieważ żadne flagi głębokości są określone, to przeszuka rekursywnie dla wszystkich podfolderów
  • -name myFile: znaleźć pliki z wyraźną nazwą myFile
  • -exec: dla wyników wyszukiwania, należy wykonać dodatkowe polecenia z nich
  • cp /home/myuser/myFile {}: kopie /home/myuser/myFile, aby nadpisać każdy wynik zwrócony przez find do; pomyśl o {} jako o miejscu każdego wyniku wyszukiwania.
  • ';': stosowane do oddzielenia różnych poleceń do uruchomienia po find
+0

Po prostu zmień kolejność {} na drugą pozycję, po/home/myuser/myFile, a to zadziała. Dzięki. –

+0

@ LuisAndrésGarcía, ah, mógłbym źle cię zrozumieć - chciałeś skopiować jeden plik '/ home/myuser/myFile', aby nadpisać' mójplik' znaleziony przez 'find' w cwd? –

+0

Masz rację! :) Kolejny przykład, aby wyświetlić właściwości dowolnego znalezionego pliku to: find -exec ls -l {} ';' –

2

Rura wyśle ​​wyjście jednego programu do wejścia drugiego. cp nie odczytuje ze swojego strumienia wejściowego na terminalu, a jedynie używa argumentów w wierszu poleceń.

Chcesz użyć albo xargs z rurą, albo z argumentem find z exec zamiast z rurami.

+2

można dać przykład , Proszę? Dziękuję Ci bardzo. –

3

Istnieje kilka sposobów, aby rozwiązać ten problem, w zależności od tego, czy trzeba się martwić plików ze spacjami lub innymi znakami specjalnymi w ich nazwach.

Jeśli żadna z nazw plików nie zawiera spacji ani znaków specjalnych (składają się one tylko z liter, cyfr, myślników i podkreśleń), poniższe rozwiązanie jest proste. Możesz użyć polecenia $(command), aby wykonać polecenie, i wstaw wyniki do argumentów innego polecenia. Powłoka podzieli wynik na spacje, tabulacje lub znaki nowej linii, a następnie for przypisze każdą wartość kolejno do $f i uruchomi polecenie dla każdej wartości.

for f in $(find . -name myFile) 
do 
    cp something $f 
done 

Jeśli masz spacje lub tabulatory, możesz użyć opcji find's -exec. Przekazujesz -exec command args, umieszczając {} w miejscu, gdzie chcesz zastąpić nazwę pliku i kończąc argumenty na ;. Musisz zacytować {} i ;, aby powłoka ich nie interpretowała.

find . -name myFile -exec cp something "{}" \; 

Czasami -exec nie jest wystarczający. Na przykład w wersji this question chcieli użyć rozszerzenia parametrów Bash do obliczenia nazwy pliku. Aby to zrobić, musisz podać -exec bash -c 'your command', ale wtedy będziesz miał problemy z cytowaniem z substytucją {}. Aby rozwiązać ten problem, można użyć -print0 z find wydrukować wyniki rozdzielany znakami NUL (które są nieprawidłowe w nazwach plików), a rura jest do while read pętli, która dzieli parametry na wartości null:

find . -name myFile -print0 | (while read -d $'\0' f; do 
    cp something "$f" 
    done) 
Powiązane problemy