Przenoszenie plików za pomocą find + xargs: cel nie jest katalogiem?

9

Po uruchomieniu następującego polecenia:

> mkdir some_dir
> find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} some_dir

Dostaję setki linii, które mówią:

mv: target `/foo/bar/XX.csv` is not a directory

Dlaczego? Myślałem, że xargs wykona:

mv /foo/barXX.csv some_dir

dla każdego findznalezionego pliku . Co się dzieje? Nawiasem mówiąc, to jest z Zsh

Aktualizacja:

Aktualizacja 1:

Próbowałem:

find /foo/bar/ -name '*.csv' -print0 | xargs -0 mv {} -t some_dir

ale potem mam kilka linii, takich jak:

mv: cannot stat `{}': No such file or directory

chociaż myślę, że polecenie poprawnie przenosi moje pliki.

Aktualizacja 2:

Wydaje mi się, że nie potrzebuję tej -topcji, kiedy korzystam mvsam. Na przykład

> touch file1.txt
> touch file2.txt
> mkdir my_dir
> mv  file1.txt  file2.txt  my_dir

działa dobrze. Dlaczego potrzebuję -tpodczas używania xargs?

Amelio Vazquez-Reina
źródło

Odpowiedzi:

14

Zakładając, że masz GNU ( find, xargs, i mv), zmienić swoje polecenia do tego:

$ find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir

fragment mvstrony man

   -t, --target-directory=DIRECTORY
          move all SOURCE arguments into DIRECTORY

Powyższe xargs ...skonstruuje polecenie, aby wywołania ruchu wyglądały następująco:

 $ mv 1.csv 2.csv 3.csv ... -t some_dir

Nie potrzebuję xargs

Możesz pominąć to podejście, po prostu findwykonując całą pracę:

$ find /foot/bar/ -name '*.csv' -exec mv -t some_dir {} +

Dlaczego potrzebne mv -t ...?

Ma to związek ze sposobem xargskonstruowania zestawu plików, które mają być przekazywane do polecenia, które będzie uruchamiane za każdym razem (tj mv ....).

Gdy mvręcznie uruchomisz polecenie samodzielnie, kontrolujesz, ile nazw plików jest do niego przekazywanych, więc nie musisz się martwić, że -t my_dirbędziesz potrzebować, ponieważ zawsze będziesz umieszczać katalog docelowy na końcu.

Bibliografia

slm
źródło
Dzięki! To jest bardzo pomocne. Jestem trochę zdezorientowany (patrz moje aktualizacje)
Amelio Vazquez-Reina
1
Skonstruowane polecenie jest mv -t some_dir 1.csv 2.csv 3.csv ...tak, że argumenty pliku są ostatnie. To jest błąd w pytaniu, aby użyć {}musisz przejść -I {}do xargs.
frostschutz
Dzięki. To wyjaśnia wszystko. Co z drugim pytaniem, które miałem w aktualizacji 2? Czy wiesz, dlaczego nie potrzebuję -twielu plików i katalogu ze zwykłym mv?
Amelio Vazquez-Reina,
1
@ user815423426 - Zaktualizuję go później, kiedy otrzymam szansę dziś wieczorem, wiem dlaczego.
slm
@ user815423426 - Zaktualizowałem pytanie, daj mi znać, czy ma to sens wrt mv -t.
slm
1

Możesz także użyć polecenia ls zamiast polecenia find:

ls /foot/bar/*.csv | xargs  mv -t some_dir
Luis Ángel Rodríguez
źródło