2016-04-13 38 views
2

Bash komut yazımı için çok yeni ve biraz alıştırma yapmak için kaynak dizini ve hedef dizini alan bir komut dosyası yazmaya çalışıyorum. Komut, kaynak dizini arayacak ve alt dizinlerin yapısını hedef dizine kopyalayacaktır (herhangi bir dosya yok sayılacak, sadece dizinlerin kendileri çoğaltılacaktır). Kaynak dizini, herhangi bir derinlikte herhangi bir sayıda alt dizine sahip olabilir. Bunu başarmanın en iyi yolu ne olurdu? Bir dizin bulunursa, bu dizinin üzerine tekrarlı olarak çağrılan bir özyinelemeli fonksiyon yazmaya çalışarak başladım. Ancak, komut dosyasıyla ilgili deneyimsizliğim yüzünden, güldüm. İşte Dizin yapısını kaynak dizinden hedef dizine kopyalamak için Bash komut dosyası

Bugüne kadar ne var:

#! /bin/bash 

if [ ! $# -eq 2 ]; then 
    echo "ERROR: Script needs 2 arguments: $0 source/directory/ target/directory/" 
    exit 
fi 

SOURCE_DIR=$1 
TARGET_DIR=$2 

function searchForDirectory { 
    for FILE in ls $SOURCE_DIR/*; do #should be 'ls *current_directory*' 
     if [ -d $FILE ]; then 
      searchForDirectory #call function recursively onto $FILE 
      #Do stuff here to create copy of this directory in target dir 
     fi 
    done 
} 

if [ ! -d $SOURCE_DIR ]; then 
    echo "ERROR: Source directory does not exist" 
    exit 
else 
    searchForDirectory 
fi 

Bu sadece bir iskelet işlevi olduğunu biliyoruz, ve daha bir çok çalışma içine koymak gerekecektir, ama sadece rehberlik arıyorum Bu konuda daha fazla gitmeden önce bunun doğru bir yol olup olmadığına ve eğer öyleyse, bir sonraki adımın ne olacağıyla ilgili olarak? Bir dizini işlevime nasıl geçiririm?

DÜZENLEME: İşte çözümüm, Ivan'ın yardımının #!/Bin/bash

if [ ! $# -eq 2 ]; then 
    echo -e "\nERROR: Script needs 2 arguments:\n$0 source/directory/ target/directory/\n" 
    exit 
fi 

function recursiveDuplication { 
    for file in `ls $1`; do 
     if [ -d $1/$file ] && [ ! -d $2/$file ]; then 
      mkdir $2/$file 
      recursiveDuplication $1/$file $2/$file 
     elif [[ $1/$file == *.png ]]; then 
      convert $1/$file $2/$file 
     fi 
    done 
} 

if [ ! -d $1 ]; then 
    echo -e "\nERROR: $1 does not exist\n" 
    exit 
elif [ -d $2 ] && [ ! -w $2 ]; then 
    echo -e "\nERROR: You do not have permission to write to $2\n" 
    exit 
elif [ ! -d $2 ]; then 
    echo -e "\nSUCCESS: $2 has been created" 
    mkdir $2 
fi 

recursiveDuplication $1 $2 

bu çözüm ile iki sorun vardır:

  1. Rany Albeg Wein Aşağıda açıklandığı gibi, 'ls' kullanarak iyi bir çözüm değil - ve gördüğüm neden orada dizin/*. png adındaki boşluk.

  2. Ayrıca herhangi bir * .png dosyasını kaynaktan hedefe kopyalamaya ve hedefte bir * .jpg görüntüsüne dönüştürmeye çalışıyorum. Bunu nasıl yapabilirim? ImageMagick'in convert image.png image.jpg komutunu kullanmaya çalışıyorum ama image.png$file olarak adlandırılırken nasıl yapıldığını bilmiyorum?

+0

Eğer ilgileniyorsanız, 'bul 've' cpio' ile yapılabilir. kaynak bul -type d | cpio -pd hedefi. 'Kaynak'tan gelen bütün ağaç' hedefe 'kopyalanır. Eğer komut "root" tarafından yürütülürse, izin ve sahiplik korunabilir. Kök olmayan tarafından çalıştırılırsa, yalnızca izin korunabilir. – alvits

+0

@KOB "gnu cpio" –

cevap

-2
#!/bin/bash 
# 1st argument - source dir, 2nd - destination 

function rrr { 
    for i in `ls $1` 
    do 
    if [ -d $1/$i ] 
    then 
     mkdir $2/$i 
     rrr $1/$i $2/$i 
    fi 
    done 
} 


rrr $1 $2 
+0

Meh -0 seçeneğini kullanmazsanız, bu, – Ivan

+0

sorudaki gibi aynıdır. Herhangi bir şey için 'ls' çıktısını kullanmayın.' ls, dizin meta verilerine etkileşimli olarak bakmak için kullanılan bir araçtır. Kod ile çıktılar bozuldu: Globs çok daha basit ve doğru: '* .txt 'dosyasındaki dosya için. [Parsing ls] (http://mywiki.wooledge.org/ParsingLs) –

+0

idem wh isimler, izinler ve sembolik bağlantılar hakkında özel karakterlerle mi? –

0

Eğer copy

$ tree a 
a 
|-- b 
| |-- c 
| | `-- file4 
| |-- d 
| | `-- file4 
| `-- file3 
`-- file2 

3 directories, 4 files 


$ tree copy 
copy 
`-- a 
    `-- b 
     |-- c 
     `-- d 

4 directories, 0 files 
+0

kullanarak test edilmiş güvenli bir çözümle yeni bir yanıt eklenmiştir. OP, izin ve sahipliğin korunup korunmayacağını belirtmemesine rağmen, bunlardan hiçbirinin bu yöntemle korunmayacağından bahsetmelisiniz. – alvits

+0

Ayrıca özel chars ('' '' '' '' '' '' '' 'n' 'n' 'n' nı içeren dizin isimleri, bu sembolik bağlantılardan ne anlama gelir? –

+0

dahası 'mkdir' Daha önce var olan dizinleri oluşturma girişiminde bulunacaktır. '-p' nedeniyle, hatalar üreterek oluşturuldu, doğru? –

0

Bu çözüm altında bir sürü

$ find a -type d | xargs -I d mkdir -p copy/d 

kopya yeni dizine dizine a gelen ağaç yapısı kolaylaştırabilirsiniz içeren dizin adları ile test edilmiştir özel karakterler, dizin ağacında bir döngü ve kırık bir sembolik bağlantı.

bir stansard çözümü feryat vardır:

(cd source/ ; find . -depth -type d -printf "%p\0" | xargs -0 -I xxx mkdir -p ../destination/xxx) 

Ve gnu cpio kullanarak ikinci bir çözüm yoktur:

(cd source/ ; find . -depth -type d -printf "%p\0" | cpio --null -pd ../destination) 

testi:

$ mkdir -p source/a/ba/c/d/e 
$ mkdir -p source/a/bb/c/d/e 
$ mkdir -p source/a/b/ca/d/e 
$ ln -s source/broken/link source/a/ba/c/d/e/broken 
$ (cd source/a/ba && ln -s ../../a tree-loop) 
$ mkdir -p source/z/"$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47\72\73\74\75\76\77\100\133\134\135\1336\137\140\173\174\175\176\177dir")" 
$ touch source/a/b/"$(printf "\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17\20\21\22\23\24\25\26\27\30\31\32\33\34\35\36\37\40\41\42\43\44\45\46\47\72\73\74\75\76\77\100\133\134\135\1336\137\140\173\174\175\176\177file")" 
$ ls 
source 
$ find source -depth 
source/z/??????????????????????????????? !"#$%&':;<=>[email protected][\][6_`{|}~?dir 
source/z 
source/a/ba/tree-loop 
source/a/ba/c/d/e/broken 
source/a/ba/c/d/e 
source/a/ba/c/d 
source/a/ba/c 
source/a/ba 
source/a/b/ca/d/e 
source/a/b/ca/d 
source/a/b/ca 
source/a/b/??????????????????????????????? !"#$%&':;<=>[email protected][\][6_`{|}~?file 
source/a/b 
source/a/bb/c/d/e 
source/a/bb/c/d 
source/a/bb/c 
source/a/bb 
source/a 
source 

$ (cd source/ ; find . -depth -type d -printf "%p\0" | xargs -0 -I xxx mkdir -p ../destination/xxx) 
$ find destination/ -depth 
destination/z/??????????????????????????????? !"#$%&':;<=>[email protected][\][6_`{|}~?dir 
destination/z 
destination/a/ba/c/d/e 
destination/a/ba/c/d 
destination/a/ba/c 
destination/a/ba 
destination/a/b/ca/d/e 
destination/a/b/ca/d 
destination/a/b/ca 
destination/a/b 
destination/a/bb/c/d/e 
destination/a/bb/c/d 
destination/a/bb/c 
destination/a/bb 
destination/a 
destination/ 

gnu cpio testi:

$ rm -rf destination 
$ (cd source/ ; find . -depth -type d -printf "%p\0" | cpio --null -pd ../destination) 
0 blocks 

$ find destination -depth 
destination/z/??????????????????????????????? !"#$%&':;<=>[email protected][\][6_`{|}~?dir 
destination/z 
destination/a/ba/c/d/e 
destination/a/ba/c/d 
destination/a/ba/c 
destination/a/ba 
destination/a/b/ca/d/e 
destination/a/b/ca/d 
destination/a/b/ca 
destination/a/b 
destination/a/bb/c/d/e 
destination/a/bb/c/d 
destination/a/bb/c 
destination/a/bb 
destination/a 
destination