Daha önce bu konuda utanç verici bir yanıt almıştım ancak Denis'in cevabı en temel şeyi özlediğimi hatırlattı. Böylece orijinal cevabımı sildim. Fakat hiç kimse bu çok temel şeyi söylemediğinden , onu buraya koymaya değeceğini düşünüyorum.
Asıl soru "Boşluktan ayrılmış dosya adlarının bir listesini içeren bir metin dosyam var. Bunları bir hedef dizine nasıl kopyalarım?" İlk başta bu biraz karmaşık veya karmaşık görünebilir, çünkü dosyadaki öğeleri bir şekilde belirli bir şekilde çıkarmanız gerektiğini düşünüyorsunuz. Bununla birlikte, kabuk bir komut satırını işlediğinde, yaptığı ilk şey argüman listesini belirteçlere ayırır ve (işte hiç kimse tam olarak söylemediği bit) ayrı belirteçleri boşluklar . (Newlines ayrıca ayrı simgeleri belirttiğinden, bu nedenle Doug Harris'in yeni satırlı ayrılmış bir listeyle yaptığı test aynı sonucu vermiştir.) Kabuk, boşluktan ayrılmış bir listeyi bekler ve zaten işleyebilir.
Dolayısıyla burada yapmanız gereken tek şey boşlukla ayrılmış listeyi (zaten sahip olduğunuz) emrinizde doğru yere koymak. Komutunuz bu konuda bir varyasyon:
cp file1 file2 file3...file# target
Tek kırışıklık, metin dosyanızdan 1 ile # arasındaki dosyaların listesini almak istemenizdir.
Dennis'in yorumunda işaret ettiği gibi, orijinal girişiminiz ( cp
cat list.txt new_folder
) çoktan işe yaramalıydı . Niye ya? Çünkü iç komut cat list.txt
önce kabuk tarafından işlenir ve genişler file1 file2 file3...file#
, bu tam olarak kabuğun komutun bu bölümünde beklediği ve istediği şeydir. Eğer işe yaramadıysa (1) ya da bir yazım hatası vardı ya da (2) dosya adlarınız bir şekilde tuhaftı (boşlukları ya da sıra dışı karakterleri vardı).
Tüm Dennis'in cevaplarının çalışmasının nedeni, cp
üzerinde çalışılacak dosyalar listesini sağlamaları ve bu listeyi tüm komutun içinde yer almasıdır. Yine komutun kendisi şu şekildedir:
cp list-of-files target_directory
Tüm bunların bu sürümde nasıl bir araya geldiğini görmek kolaydır:
cp $(<list.txt) new_folder
$()
kabuğun parantez içindeki komutu çalıştırmasına ve daha sonra çıktısını daha büyük satırdaki yerine koymasına neden olur. Sonra kabuk çizgiyi bir bütün olarak çalıştırır. Bu arada, $()
zaten backtick'lerle yaptığın şeyin daha modern bir versiyonudur (`). Sonraki: <
bir dosya yönlendirme operatörü. Kabuğa içeriğini list.txt
standart girdilere dökmesini söyler . Yana $()
biraz ilk işlemden geçiyor burada aşamada gerçekleşir:
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
Açıkçası 2. adım basitçe istediğiniz normal cp
komuttur.
Bu (belki de çok ölü) atı çokça attığımın farkındayım, ama bence yapmaya değer. Kabuğun bir komutu tam olarak nasıl işlediğini anlamak , onu daha iyi yazmanıza ve çok basitleştirmenize yardımcı olabilir. Ayrıca, sorunların nerede gizlenebileceğini gösterir. Bu durumda, örneğin, size ilk sorum komik dosya isimleri veya olası bir yazım hatası ile ilgili olmalıydı. Akrobasi gerekmez.