Salin setiap file dalam struktur direktori ke jalur tertentu hanya jika file belum ada di sana

8

Ingin menyalin setiap file dari struktur direktori ke direktori tertentu hanya jika file belum ada di sana.

Dapatkan bagian pertama dari pertanyaan Stack Overflow ini :

find . -type f -exec cp {} /target-directory \;

Bagaimana saya bisa mengecek apakah file itu ada atau tidak? Jika tidak, salin file, jika tidak lewati.

Tuan au
sumber
Apakah maksud Anda "menyalin semua file di pohon sumber ke direktori tunggal (spesifik) tanpa subdirektori"? Atau "salin semua file di pohon sumber ke subdirektori dari direktori tujuan yang mirip dengan di mana itu di pohon sumber"? Saya membaca pertanyaan sebagai kasus pertama - dapatkah Anda mengedit pertanyaan untuk menjelaskan? (Saya tahu Anda punya jawaban, tetapi akan dibaca, dan digunakan, oleh orang lain.)
Volker Siegel

Jawaban:

13

Anda dapat menggunakan perintah -uberalih dari cp:

salin hanya ketika file SOURCE lebih baru dari file tujuan atau ketika file tujuan hilang

atau gunakan rsyncperintah dengan --ignore-existing:

lewati memperbarui file yang ada pada receiver

Contoh:

rsync --ignore-existing source/* destination/
Ravexina
sumber
3

Perintah asli Anda dapat ditulis ulang sebagai:

find . -type f -exec bash -c 'test -e /target-directory/"$1" || cp "$1" /target-directory' sh {} \;

Kuncinya di sini adalah kita memanggil shell dengan perintah khusus dan meneruskan file yang ditemukan sebagai $1argumen. Jika test -e /target-directory/"$1"gagal, itu berarti file tidak ada, dalam hal ini cpakan menyalin file.

Secara umum, seseorang dapat menggunakan perintah lain, selama perintah itu dapat memverifikasi keberadaan file. Beberapa alternatif lain:

  • /usr/bin/realpath -e /target-directory/"$1" > /dev/null || cp "$1" /target-directory
  • stat >/dev/null /target-directory/"$1" || cp "$1" /target-directory/"$1"
Sergiy Kolodyazhnyy
sumber
2
Mengapa statharus menguji keberadaan file di Bash? Bukankah test -elebih sederhana?
David Foerster
@ DavidFoerster Tidak ada alasan khusus. perintah uji akan melakukannya juga. Saya akan mengedit jawaban saya nanti jika saya tidak lupa
Sergiy Kolodyazhnyy
0

Baca man cp, dan gunakan --no-clobberopsi untuk cp.

waltinator
sumber