2016-04-13 4 views
2

Ich bin sehr neu Bash scritping und bekommt einige Übung zu kopieren, ich bin versucht, ein Skript zu schreiben, die in einem Quellverzeichnis und ein Zielverzeichnis erfolgt. Das Skript durchsucht das Quellverzeichnis und kopiert seine Unterverzeichnisstruktur in das Zielverzeichnis (alle Dateien werden ignoriert, nur die Verzeichnisse selbst werden dupliziert). Das Quellverzeichnis kann beliebig viele Unterverzeichnisse enthalten. Was wäre der beste Weg, dies zu erreichen? Ich habe mit dem Versuch begonnen, eine rekursive Funktion zu schreiben, bei der, wenn ein Verzeichnis gefunden wird, die Funktion rekursiv auf dieses Verzeichnis aufgerufen wird. Aufgrund meiner mangelnden Erfahrung mit Skripten bin ich jedoch ratlos. HierBash-Skript die Verzeichnisstruktur von Quellverzeichnis in dem Zielverzeichnis

ist das, was ich bisher:

#! /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 

Ich weiß, dass dies nur ein Skelett-Funktion und eine Menge mehr Arbeit müsste in sie werden gestellt, aber ich bin nur für die Führung ob dies der richtige Weg ist, bevor ich weiter gehe, und wenn ja, was wäre mein nächster Schritt? Wie gebe ich ein Verzeichnis in meine Funktion ein?

EDIT: Hier ist meine Lösung dank Ivans Hilfe unter #!/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 

Es gibt zwei Probleme mit dieser Lösung:

  1. Wie Rany Albeg Wein unten erläutert wird, 'ls' verwendet, ist keine gute Lösung - und ich habe gesehen, warum, wenn es ist ein Leerzeichen in einem Verzeichnis/*. png Name.

  2. Ich versuche auch, eine * .png Datei von der Quelle zum Ziel zu kopieren und sie in ein * .jpg Bild im Ziel umzuwandeln. Wie kann ich das machen? Ich versuche ImageMagicks convert image.png image.jpg Befehl zu verwenden, aber nicht wissen, wie dies zu tun, wenn die image.png wird als $file bezeichnet wird?

+0

Wenn Sie interessiert sind, kann es durch 'find' und' cpio' erreicht werden. 'finde Quellentyp - d | cpio -pd Ziel'. Der gesamte Baum von "source" wird nach "target" kopiert. Wenn der Befehl von "root" ausgeführt wird, können Berechtigungen und Besitzrechte beibehalten werden. Wenn es von einem Nicht-Stammverzeichnis ausgeführt wird, kann nur die Berechtigung beibehalten werden. – alvits

+0

@KOB Eine neue Antwort wurde mit einer getesteten sicheren Lösung hinzugefügt, die 'gnu cpio' verwendet –

Antwort

-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, das ist das gleiche, wie in Frage – Ivan

+0

Verwenden Sie nicht 'ls' Ausgabe für irgendetwas.' ls' ist ein Werkzeug für interaktiv Blick auf Verzeichnis-Metadaten 'ls' Ausgabe mit Code ist kaputt. Globs sind viel einfacher UND korrekt: ' für Datei in * .txt'. Lesen [Parsing ls] (http://mywiki.wooledge.org/ParsingLs) –

+0

idem wh über spezielle Zeichen in Namen, Berechtigungen und symbolischen Links? –

0

Sie können viel vereinfachen

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

Kopie der Baumstruktur aus dem Verzeichnis a neue Verzeichnis unter 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

Obwohl das OP nicht angegeben hat, ob er die Berechtigung und den Besitz behalten soll, sollten Sie erwähnen, dass keine davon mit dieser Methode erhalten bleibt. – alvits

+0

Außerdem werden Verzeichnisnamen, die spezielle Zeichen enthalten ('' '' '' '' '' '' '' '' '' 'n '), diese symbolischen Links brechen? –

+0

Außerdem' mkdir' wird versuchen, Verzeichnisse zu erstellen, die bereits haben wurde erstellt wegen '-p', Fehler erzeugen, richtig? –

0

Diese Lösung wurde mit Verzeichnisnamen getestet enthalten spezielle Zeichen, eine Schleife im Verzeichnisbaum und eine unterbrochene symbolische Verbindung.

Es ist unten eine Stansard Lösung:

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

Und es gibt eine zweite Lösung mit gnu cpio:

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

Der Test:

$ 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/ 

Der gnu cpio Test:

$ 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 
Verwandte Themen