Linux (mv atau cp) file spesifik dari daftar teks file?

34

Saya memiliki direktori banyak file, seperti 50.000 pdf dan file lainnya di server. Saya perlu memindahkan yang spesifik ke direktori lain. Saya dapat membuat daftar file yang perlu dipindahkan baik dalam csv atau format teks lainnya.

Yang perlu saya lakukan adalah menjalankan skrip bash dan memindahkan atau menyalin file yang tercantum dalam file teks ke direktori lain.

Apakah ada cara mudah untuk melakukan ini? Setiap saran atau sumber daya akan sangat dihargai.

Jestep
sumber
Juga, file-file tersebut dinamai secara acak ketika mereka ditambahkan ke direktori. Tidak ada konvensi penamaan atau logika apa pun yang dapat digunakan untuk memindahkan file tertentu.
Jestep

Jawaban:

26

rsync memiliki beberapa pilihan yang dapat mengambil daftar file untuk proses ( --files-from, --include-from, dll).

Sebagai contoh, ini akan melakukan trik:

rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
Ignacio Vazquez-Abrams
sumber
2
contoh:rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
anneb
28

Untuk menghindari penggunaan yang tidak berguna cat(dan jika Anda tidak menggunakan rsync):

xargs -a file_list.txt mv -t /path/to/dest

Ini akan menangani nama file yang valid, kecuali jika berisi baris baru, jika file terdaftar satu per baris.

Dijeda sampai pemberitahuan lebih lanjut.
sumber
2
Salah satu kelemahan dari pendekatan ini adalah bahwa jika file dalam daftar berisi nama path (yaitu mereka tidak semua berada di direktori yang sama), penggunaan mvakan meruntuhkan semuanya ke direktori tujuan yang sama. The rsyncpendekatan dalam jawaban yang diterima tidak menderita dari keterbatasan ini.
Jason R
Juga, saya mencoba perintah ini dan xargs akan merusak semua file yang berisi kutipan tunggal ("kutipan tunggal tak tertandingi")
James Beninger
Ini berhasil bagi saya karena saya sebenarnya menginginkan file dari jalur sumber yang berbeda di direktori target yang sama.
PseudoNoise
15
for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

dengan asumsi bash, ditambah listoffilesmengandung satu file per baris. Satu-satunya keberatan saya terhadap rute rsync adalah bahwa OP meminta metode untuk memindahkan file, bukan menyalinnya. rsync memiliki lebih banyak bendera daripada pernikahan kerajaan, jadi saya yakin ini dapat dimodifikasi lebih lanjut untuk melakukan itu, tetapi terkadang lebih sederhana lebih baik!

MadHatter mendukung Monica
sumber
1
Solusi ini menurut saya paling fleksibel. Saya akhirnya menggunakannya dengan rsync bukan cp atau mv hanya karena saya memerlukan opsi path file relatif.
Spamwich
4
Bagus, hanya saya punya masalah dengan spasi, jadi saya memodifikasinya menjadi:while read -r file; do mv "$file" /path/of/destination ; done < listoffiles
user1182474
1
@ user1182474 Terima kasih, dan penggunaan redirection input yang elegan. Metode tradisional untuk menunjukkan kepuasan dengan jawaban adalah dengan mengungguli, omong-omong!
MadHatter mendukung Monica
1
@ user1182474 terima kasih untuk itu! langkah terakhir dalam banyak modifikasi harus agak membabi buta untuk membuat porting utilitas cadangan OSX saya ke Android saya!
Charlie Gorichanaz
4

Ini tergantung pada format file teks yang Anda miliki. Misalnya, jika Anda memiliki daftar file yang ditulis sehingga Setiap file terletak pada baris baru. Anda dapat menggunakan xargs seperti:

$ cat your_text_file | xargs cp -t /path/to/destination

Anda juga dapat menggunakan findperintah dengan -execopsi. untuk menyalin / memindahkan file.

Khaled
sumber
3
rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync memiliki manfaat tambahan atas perintah cpatau mvkarena perintah itu akan secara otomatis membuat folder jika tidak ada.

Paul Wenzel
sumber
Mengapa /path/to/sourcediperlukan saat mengambil jalur dari daftar file?
bzero
@ bzero mungkin daftar file dapat berisi jalur relatif?
DreadfulWeather
2

Saya pikir jawaban rsync adalah jawaban yang lebih baik, tetapi hanya untuk opsi lain:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)
jj33
sumber
Ini bagus untuk Dockerfile, karena tar tersedia di gambar dasar ubuntu, tetapi tidak rsync.
kristianp
1

Saya tidak sengaja menyalin isi lengkap direktori ke direktori tujuan alih-alih memindahkan direktori lengkap. Ini menghasilkan direktori tujuan yang berantakan bukannya direktori asal yang ditambahkan ke direktori.

Untuk memperbaiki ini, saya melakukan hal berikut:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove Perintah di atas membuat file filestomove yang akan menjadi daftar semua konten direktori tujuan, dibalik diurutkan berdasarkan waktu, yang berarti terlama hingga terbaru.

Lalu saya membuat sub-direktori dari direktori tujuan yang sekarang berantakan untuk memindahkan barang-barang ke.

mkdir /path/to/cluttered/destination/directory/newsubdirectory

Kemudian saya mengulang daftar direktori, kecuali daftar ke layar dan menunjukkan lebih banyak detail.

ls -lrht /path/to/cluttered/destination/directory/ Baris ini daftar direktori, diurutkan berdasarkan tanggal naik (urutan mundur berdasarkan waktu) dan menunjukkan informasi lebih lanjut, termasuk cap tanggal / waktu dari setiap file di direktori tujuan yang sekarang berantakan. Saya merujuk ini, mulai dari atas untuk menunjukkan direktori dan file apa yang ingin saya simpan di mana mereka berada. Akan ada celah dalam cap tanggal / waktu file di mana semua file baru mulai yang seharusnya tidak ada.

Kemudian saya mengedit file filestomove yang dibuat pada langkah pertama di atas (yang diurutkan berdasarkan tanggal) dan menghapus beberapa dari daftar yang ada sebelumnya yang ingin saya tinggal dari direktori asli.

vim /opt/dircheck/filestomove Hapus dari atas, semua file yang tidak ingin Anda pindahkan.

Kemudian saya menggunakan perintah yang tercantum sebelumnya dalam posting ini untuk memindahkan file dalam daftar saya ke direktori baru yang saya buat.

sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

Ini memindahkan semua file dalam sepersekian detik. (Catatan: Anda mungkin tidak memerlukan sudo di awal, ini masalah izin file).

Sekarang direktori tujuan asli saya bagus dan bersih dan berisi direktori baru dengan semua file dan direktori yang berantakan itu.

John
sumber
1

Jika (dan hanya jika), Anda tidak memiliki karakter jahat dalam nama file (spasi, baris baru, yang akan membingungkan xargs tentang cara memecah hal-hal menjadi argumen individu), dan Anda menghasilkan daftar file yang dipisahkan oleh baris baru (satu file) per baris), Anda bisa melakukan sesuatu seperti.

cat filenames.txt | xargs mv -t /path/to/move/files/to

(Secara umum, lihat man xargs , ini luar biasa)

Jika mv Anda tidak memiliki opsi -t, Anda juga bisa melakukan beberapa tipu muslihat

( cat filenames.txt; echo; echo /path/to/move/files/to ) | xargs mv

Catatan - tak satu pun dari ini akan berfungsi seperti yang diharapkan jika ada nama file dengan baris baru di dalamnya.

Kjetil Joergensen
sumber
Namun; lihat jawaban Ignacio, rsync dibuat khusus untuk hal ini.
Kjetil Joergensen
cp, mvdan sejenisnya tidak memiliki -topsi pada bsd , dan contoh kedua dengan subkulit tidak berfungsi untuk saya ( /path/to/moveditambahkan sebagai nama file terakhir)
1
@ w17t - terdengar seperti filenames.txt tidak berakhir dengan baris baru, baik tambahkan baris baru ke akhir filenames.txt, atau lakukan sesuatu seperti(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mv
Kjetil Joergensen
0

Coba sesuatu seperti:

cat list.txt | while read line; do mv "$line" /images; done
AliGibbs
sumber
bisa while read line; do mv $line /images; done < list.txt sebagai satu perintah
ignivs
0

Berikut ini berfungsi untuk saya di mana saya perlu menyalin semua file PNG dari jalur tertentu (dan semua subdirs) ke lokasi baru sambil mempertahankan struktur direktori:

rsync -av --prune-empty-dirs --include='*/' --include='*.png' --exclude='*' source/ destination/

Karena RSYNC menciptakan mirror dari struktur direktori terlebih dahulu, kemudian menyinkronkan file, Anda dapat berakhir dengan folder berlebih yang kosong. Saya menggunakan flag --prune-empty-dirs untuk menghapus direktori kosong ini.

Saya tidak memiliki afiliasi, tetapi berpikir benar untuk memberi kredit kepada sumber yang mengilhami solusi ini: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/

John Mark Mitchell
sumber