Saya memiliki daftar file yang dipisahkan oleh spasi dalam file list.txt
. Saya ingin menyalinnya ke folder baru.
Saya mencoba melakukan:
cp `cat list.txt` new_folder
tapi itu tidak berhasil.
Bagaimana Anda melakukan ini?
Memperbarui:
Terima kasih atas semua jawaban Anda yang sangat menarik. Saya tidak banyak meminta :)
Setelah mencoba solusi di atas untuk yang kedua kalinya, tampaknya cp
bantuan penggunaan cetak karena folder new_folder
belum ada! Maaf, ini kelihatannya merupakan kesalahan bodoh ... Ketika saya membuat folder sebelumnya, itu berfungsi.
Namun, saya telah belajar banyak dari semua jawaban dan solusi Anda, terima kasih atas waktu yang Anda berikan untuk menulisnya.
Jawaban:
Coba gunakan xargs:
Memperbarui:
Saya melakukan ini pada OS X yang memiliki versi berbeda dari versi GNU / Linux. Yang
xargs
berasal dari GNU findutils tidak memiliki-J
tetapi memiliki-I
yang serupa (seperti yang ditunjukkan oleh Dennis Williamson dalam komentar). Versi OS X dari xargs memiliki keduanya-I
dan-J
yang memiliki perilaku yang sedikit berbeda - keduanya akan berfungsi untuk pertanyaan asli ini.sumber
xargs
tidak memilikinya-J
memiliki-I
yang tampaknya melakukan hal yang sama. Versixargs
apa dan OS / distribusi apa yang Anda miliki?xargs --version
mengembalikan pesan kesalahan penggunaan. Kemungkinan versi xargs BSD. Penggunaan-I
dan-J
agak berbeda. Saya akan memperbarui jawaban saya dengan contoh yang diformat dengan baik.-J
dan-I
:)Tidak perlu
cat
sama sekali:Atau menggunakan opsi panjang:
Berikut ini beberapa versi shell. Perhatikan bahwa beberapa variabel tidak dikutip atau
for
loop digunakan secara khusus karena OP menetapkan bahwa nama file dibatasi oleh ruang. Beberapa teknik ini tidak akan berfungsi untuk input nama file per baris di mana nama file berisi ruang putih.Pesta:
atau
sh (atau Bash):
atau
atau
atau
sumber
-t
diperlukanxargs -a list.txt cp -t new_folder
?-t
Opsi untukcp
. Ini menyalin semua argumen sumber ke direktori target yang ditentukan. Di sini, ini memungkinkan target untuk ditentukan sebelum sumber yang ditambahkan olehxargs
perintah.Saya punya jawaban yang memalukan di sini sebelumnya, tetapi jawaban Denis mengingatkan saya bahwa saya melewatkan hal yang paling mendasar. Jadi, saya menghapus jawaban asli saya. Tetapi karena tidak ada yang mengatakan hal yang sangat mendasar ini, saya pikir ada baiknya untuk meletakkannya di sini.
Pertanyaan aslinya adalah "Saya memiliki file teks dengan daftar nama file yang dipisahkan oleh ruang. Bagaimana saya bisa menyalinnya ke satu direktori target." Pada awalnya ini mungkin tampak rumit atau rumit, karena Anda berpikir Anda harus mengekstraksi item dari file dengan cara tertentu. Namun, ketika shell memproses sebuah baris perintah, hal pertama yang dilakukannya adalah memisahkan daftar argumen menjadi token dan (di sini sedikit yang tidak ada yang mengatakan langsung) spasi token yang terpisah . (Newlines juga memisahkan token yang mengapa pengujian Doug Harris dengan daftar yang dipisahkan dengan baris baru memiliki hasil yang sama.) Yaitu, shell mengharapkan dan sudah dapat menangani daftar yang dipisahkan oleh ruang.
Jadi yang perlu Anda lakukan di sini adalah meletakkan daftar yang dipisahkan oleh ruang (yang sudah Anda miliki) ke tempat yang tepat dalam perintah Anda. Perintah Anda adalah beberapa variasi dalam hal ini:
Satu-satunya kerutan adalah Anda ingin mendapatkan daftar file 1 hingga # dari file teks Anda.
Seperti yang ditunjukkan oleh Dennis dalam komentarnya, upaya awal Anda (
cp
cat list.txtnew_folder
) seharusnya sudah berhasil. Mengapa? Karena perintah internalcat list.txt
diproses terlebih dahulu oleh shell dan berkembang menjadifile1 file2 file3...file#
, yang persis seperti yang diharapkan dan diinginkan shell pada bagian perintah itu. Jika tidak berhasil maka (1) Anda salah ketik atau (2) nama file Anda entah bagaimana aneh (mereka memiliki spasi atau karakter tidak biasa lainnya).Alasan semua jawaban Dennis bekerja adalah karena mereka menyediakan daftar file yang diperlukan untuk
cp
dikerjakan, menempatkan daftar itu di tempat yang termasuk dalam seluruh perintah. Sekali lagi, perintah itu sendiri adalah struktur ini:Sangat mudah untuk melihat bagaimana semua ini menyatu dalam versi ini:
$()
menyebabkan shell menjalankan perintah di dalam tanda kurung dan kemudian mengganti outputnya pada titik tersebut di baris yang lebih besar. Kemudian shell menjalankan garis secara keseluruhan. Omong-omong,$()
adalah versi yang lebih modern dari apa yang sudah Anda lakukan dengan backticks (`). Berikutnya:<
adalah operator pengalihan file. Ia memberi tahu shell untuk membuang kontenlist.txt
ke input standar. Karena$()
bit diproses terlebih dahulu, inilah yang terjadi secara bertahap:cp $(<list.txt) new_folder
# split line into three tokens: cp, $(<list.txt), new_folder
cp file1 file2 file3...file# new_folder
# substitute result of $(<list.txt) into the larger command
Jelas langkah 2 hanyalah
cp
perintah normal yang Anda inginkan.Saya menyadari bahwa saya sering mengalahkan kuda ini (mungkin sangat mati), tetapi saya pikir ini layak dilakukan. Memahami persis bagaimana shell memproses suatu perintah dapat membantu Anda untuk menulisnya dengan lebih baik dan menyederhanakan banyak hal. Ini juga akan menunjukkan kepada Anda di mana masalah cenderung bersembunyi. Dalam kasus ini, misalnya, pertanyaan pertama saya kepada Anda seharusnya tentang nama file lucu atau kemungkinan kesalahan ketik. Tidak diperlukan akrobat.
sumber
--parents
benderanya. Anda dapat membuatnya dengan kata lain-v
untuk catatan apa yang telah disalin. Jika Anda ingin mempertahankan izin, Anda memerlukan tanda-a
atau-p
. Yaitucp --parents -av $(<list.txt) new_folder
,. Ini semua dengan asumsi daftar file Anda benar-benar semua file, kalau tidak, Anda mungkin juga perlu-r
menandai untuk muncul kembali.--parents
bendera itu tidak ada di sana. Versi mereka (yang diturunkan dari BSD)cp
hanya menyediakan opsi pendek, bukan opsi panjang gaya GNU. Untuk gaya BSDcp
, flag untuk salinan rekursif adalah huruf besar-R
, bukan huruf kecil.