2017-01-23 1 views
1

Ich arbeite an einem scp Anruf, um einen Ordner herunterzuladen, der auf einem Remote-System vorhanden ist. Heruntergeladenen Ordner hat Unterordner und innerhalb dieser Unterordner gibt es eine Reihe von Dateien, die ich als Argumente für ein Python-Skript wie folgt übergeben möchten:Wie rekursiv durchqueren Sie einen Verzeichnisbaum und finden nur Dateien?

scp -r [email protected]:SomeName/SomeNameElse/$folder_name/ $folder_name/ 
echo "File downloaded successfully" 
echo "Running BD scanner" 
for d in $folder_name/*; do 
     if [[ -d $d ]]; then 
       echo "It is a directory" 
     elif [[ -f $d ]]; then 
       echo "It is a file" 
       echo "Running the scanner :" 
       python bd_scanner_new.py /home/nsadmin/Some/bash_script_run_files/$d 
     else 
       echo "$d is invalid file" 
       exit 1 
     fi 
done 

ich die Logik hinzugefügt haben, um herauszufinden, ob es irgendwelche Verzeichnisse sind und ohne sie . Ich durchlaufe diese Verzeichnisse jedoch nicht rekursiv.

Teil Ergebnisse unter:

File downloaded succesfully 
Running BD scanner 
It is a directory 
It is a directory 
It is a directory 
Exiting 

Ich möchte diesen Code verbessern, so dass sie alle Verzeichnisse durchläuft und alle Dateien aufnimmt. Bitte helfen Sie mir bei Vorschlägen.

Antwort

1

Warum gehen Sie durch die Probleme der Verwendung von globbing für die Dateiübereinstimmung, sondern verwenden Sie find mit dafür ist eine Prozess-Substitution (<()) mit einer While-Schleife.

#!/bin/bash 

while IFS= read -r -d '' file; do 
    # single filename is in $file 
    python bd_scanner_new.py "$file" 
done < <(find "$folder_name" -type f -print0) 

Hier find hat eine rekursive Suche aller Dateien aus dem genannten Pfad zu jeder Ebene der Unterverzeichnisse unten. Dateinamen können Leerzeichen, Tabulatoren, Leerzeichen und Zeilenumbrüche enthalten. Um Dateinamen auf sichere Weise zu verarbeiten, wird mit -print0 gefunden: Dateiname wird mit allen Steuerzeichen & gedruckt, die mit NUL abgeschlossen sind, die dann read Befehlsabläufen mit demselben De-Limit-Zeichen sind.

Hinweis; Nebenbei, zitieren Sie Variablen immer in bash, um eine Erweiterung durch Shell zu vermeiden.

+0

Warum verwenden Sie eine 'while' /' read' Schleife die Ausgabe von 'find' zu analysieren (und unter Verwendung von Nicht-Standard-Funktionen) anstelle von' find' die '-exec' Schalter? ':)'. –

2

können Sie shopt -s globstar in Bash verwenden 4.0+:

#!/bin/bash 

shopt -s globstar nullglob 
cd _your_base_dir 
for file in **/*; do 
    # will loop for all the regular files across the entire tree 
    # files with white spaces or other special characters are gracefully handled 
    python bd_scanner_new.py "$file" 
done 

Bash Handbuch sagt dieses über globstar:

Wenn gesetzt, das Muster '**' verwendet, in einem Dateinamen Erweiterung Kontext wird Finde alle Dateien und null oder mehr Verzeichnisse und Unterverzeichnisse. Wenn auf das Muster ein '/' folgt, stimmen nur die Verzeichnisse und Unterverzeichnisse überein.

Mehr globstar Diskussion hier: https://unix.stackexchange.com/questions/117826/bash-globstar-matching

Verwandte Themen