Cp kullanarak tek bir dosyayı birden çok dizine kopyalama


12

Bu soru, önceki sorum için bir dizi devamı, kullanarak sayısız dizin oluşturmamkdir .

bashKabuğu kullanıyorum . Ben komut kullanarak her biri "s" önekiyle başlayan elli dizin oluşturduk:

mkdir $(printf "s%02i " $(seq 1 50))

sıfırlarla ikinci basamağa kadar doluyor. Olduğunu, ben elde dizinleri formu vardır s01, s02, ..., s49, s50.

Şimdi elli dizinin her birine cptek bir dosyayı (örneğin test.txt) kopyalamak için kullanmak istiyorum . Bunu yukarıdakine benzer bir şekilde yapmak mümkün müdür? Örneğin, aşağıdakiler işe yarar mı? Unix / Linux için nispeten yeniyim, bu yüzden birisi bana güvenli olduğunu gösteren bir işaret verene kadar bunu denemek istemiyorum.

cp test.txt $ (printf "s% 02i.txt" $ (sıra 1 50))

Baktığımızda mansayfa cp, bu gibi görünmüyor cpancak böyle desteklerle birden çok hedef:

NAME
       cp - copy files and directories

SYNOPSIS
       cp [OPTION]... [-T] SOURCE DEST
       cp [OPTION]... SOURCE... DIRECTORY
       cp [OPTION]... -t DIRECTORY SOURCE...

DESCRIPTION
       Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.

       Mandatory  arguments  to  long  options are mandatory for short options
       too.

Yanıtlar:


7

Dosyayı kullanarak her bir dizine kopyalamak için komutunuzdaki çıktıyı kullanmak cpisterseniz, her zaman aşağıdakilere yönlendirebilirsiniz xargs:

printf "s%02i " $(seq 1 50) | xargs -n 1 cp test.txt

Çıktıyı ayrıştırmanın güvenliği hakkında herhangi bir endişe olmamalıdır, çünkü formatını ve içeriğini elden önce biliyorsunuz - dosya adlarında meta karakterlerle ve boşluklarla karşılaşma riski burada gerçekten bir sorun değil.

Alternatif olarak, dizinlerin zaten var olduğunu varsayarsak, şöyle bir şey deneyebilirsiniz:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -print0 | xargs -0 -I {} cp test.txt {}

veya boru olmadan:

find . -maxdepth 1 -type d -name 's[0-9][0-9]' -exec cp test.txt {} \;

Son iki komut, geçerli dizindeki ve bu klasördeki dosyaları bulur cp test.txt. Bu -maxdepth 1seçenek, dosyayı alan tüm alt dizinleri de önler. Herhangi bir iki basamak 's[0-9][0-9]'ile eşleşen eşleştiği konusunda uyarılırsınız, yani sherhangi bir nedenle içinde olmanız durumunda s99, cwdbir kopyası da alırsınız test.txt.


8

Kabuğun yinelemeleri bir fordöngü ile yapmasına da izin verebilirsiniz . parallelVeya gibi harici araçlara dayanmayan en temel yol xargsve bunu anlamanın en kolay yolu:

for name in $(printf "s%02i " $(seq 1 50)); do
    mkdir $name
    cp test.txt $name
done

Bunu yazmanın bir milyon yolu daha var, örneğin:

for name in $(seq -w 1 50); do
    mkdir s$name
    cp test.txt s$name
done

Bunu yapmadan önce neyin yürütüleceğini doğrulamak istiyorsanız, komutları önceden eklemek gibi bir satır yapabilirsiniz echo, bu satır satırı yürütmek yerine yazdıracaktır:

for name in $(seq -w 1 50); do
    echo mkdir s$name
    echo cp test.txt s$name
done

çıktılar:

mkdir s01
cp test.txt s01
mkdir s02
cp test.txt s02
mkdir s03
cp test.txt s03
# etc.


2

GNU paralelini de kullanabilirsiniz . Text.txt içeren dizinde olduğunuzu ve 50 dizininizin /my/50dirs/path(örneğin /my/50dirs/path/s01, /my/50dirs/path/s02vb.) Bulunduğunu varsayarsak :

seq -w 01 50 | parallel -j1 cp text.txt /my/50dirs/path/s{}

2
Daha iyi yapın parallel -j1, aksi takdirde çekirdek başına bir iş olacak ve çok çekirdekli bir makinede işler IO için rekabet edecek.
Gilles 'SO- kötü olmayı kes'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.