Jak mogę skopiować plik do nowej lokalizacji, również tworząc katalog

12

Chcę cpplik do innego katalogu, ale ten katalog jeszcze nie istnieje.

Więc zrobiłbym:

mkdir /new_place
cp the_file /new_place

Czy mogę to zrobić w jednym?
Wyobrażam sobie coś takiego cp the_file -m /new_place, jak gdyby „m” oznaczało „twórz katalog, który nie istnieje”

Czy byłaby to szansa na użycie scp, rsync lub innego narzędzia do kopiowania?

Michael Durrant
źródło

Odpowiedzi:

17

Za pomocą --parentsmożesz odtworzyć katalogi ze źródła do miejsca docelowego. Na przykład:

cp --parents ~/Downloads/test.txt ~/Desktop/

Utworzy podkatalogi, ~/Desktop/home/desgua/Downloadsa następnie skopiuje test.txtdo niego; i

cp --parents Downloads/test.txt ~/Desktop/

stworzy ~/Desktop/Downloads.

desgua
źródło
5

Możesz to zrobić za pomocą następującego polecenia

# rsync --recursive the_file /path/to/your/dir/that/doesn't/exists/

Uwaga: użycie „/” na końcu ścieżki:

  • Gdy używasz „/” na końcu źródła, rsync skopiuje zawartość ostatniego folderu. Gdy nie używasz „/” na końcu źródła, rsync skopiuje ostatni folder i jego zawartość.

  • Gdy używasz „/” na końcu miejsca docelowego, rsync wklei dane do ostatniego folderu. Gdy nie używasz „/” na końcu miejsca docelowego, rsync utworzy folder z nazwą ostatniego folderu docelowego i wklei dane do tego folderu.

OrangeTux
źródło
Jeśli chcesz the_file, musisz dodać a /na końcu nowej ścieżki do katalogu.
mfink
1

Odpowiedź desgui jest właściwa i prosta, ale co, jeśli potrzebujesz drogi, którą można ochronić? POSIX definiuje cpbez --parentflagi, więc nie zadziała we wszystkich systemach.

Jedną z opcji jest napisanie go w Pythonie, jeśli jest zainstalowany w systemie:

#!/usr/bin/env python3
from os import makedirs
from os.path import exists,basename
from shutil import copyfile
from sys import argv

if len(argv) < 3:
   print('Not enough args',file=stderr)
   exit(1)

filename = basename(argv[2])
dirs = argv[2].replace(filename,'')
makedirs(dirs)
copyfile(argv[1],argv[2])

Działa to tak:

$ ./mkdircp.py /etc/passwd $HOME/foodir/bardir/passwd.copy
$ stat --printf "%F\n" $HOME/foodir/bardir/passwd.copy
regular file
$ head -n 1 $HOME/foodir/bardir/passwd.copy
root:x:0:0:root:/root:/bin/bash
Sergiy Kolodyazhnyy
źródło
0

Możesz łatwo wpisać dwa polecenia, używając; Na przykład:

mkdir folder; cp file.html folder

i powinno działać.

Galja Moehn
źródło