So verschieben Sie alle Dateien mit Bash aus mehreren Verzeichnissen in ihre übergeordneten Verzeichnisse

So verschieben Sie alle Dateien mit Bash aus mehreren Verzeichnissen in ihre übergeordneten Verzeichnisse

Ich habe folgende Dateistruktur:

  • /home/daten/C01/dir_wwe_346/datei1.txt Bild.jpg zufällig.sh
  • /home/daten/C02/dir_wwe_644/datei1.txt Bild.jpg zufällig.sh
  • /home/daten/C03/dir_wwe_324/datei1.txt Bild.jpg zufällig.sh

Ich möchte, dass sie so sind:

  • home/data/C01/file1.txt Bild.jpg random.sh
  • home/data/C02/file1.txt Bild.jpg random.sh
  • home/data/C03/file1.txt Bild.jpg random.sh

Dabei werden im Grunde mehrere Dateien ein Verzeichnis nach oben verschoben. Ich habe dieses Skript erfolglos ausprobiert:

#!/bin/bash for i in */ do cd i/*/ mv * ../ done


Nachdem ich dies gepostet hatte (aber bevor ich die Grawity-Antwort unten gelesen hatte), wurde mir klar, dass ich nicht die richtige Variablenerweiterung verwendet hatte, und führte Folgendes aus:

#!/bin/bash for i in */ do cd ${i}*wwe* mv * ../ done

Das Skript verschiebt alle Unterverzeichnisse in den Datenordner, sodass ich am Ende Folgendes erhalte:

  • /heim/C01/dir_wwe_346/datei1.txt Bild.jpg zufällig.sh
  • /heim/C02/dir_wwe_644/datei1.txt Bild.jpg zufällig.sh
  • /heim/C03/dir_wwe_324/datei1.txt Bild.jpg zufällig.sh

    Was mache ich falsch?


PS. Ich habe den Beitrag so bearbeitet, dass er den Prozess zeigt, den ich durchlaufen habe, und damit die Antworten für Neulinge, die von diesen Antworten profitieren könnten, mehr Sinn ergeben. Danke Grawity, ich habe etwas Neues gelernt. Ich habe erst vor einer Woche angefangen, Bash zu lernen, und ich habe das Gefühl, dass ich Fortschritte mache.

Antwort1

  1. Variablen werden nur mit dem $Präfix erkannt und erweitert. Wenn die Schleife eine Variable 'i' definiert, müssen Sie verwenden$iwann immer Sie den Wert benötigen:

    for i in */; do
        cd $i/*/
    
  2. Das „aktuelle Verzeichnis“ ist prozessweit gültig und wird nicht bei jedem Schleifendurchlauf automatisch zurückgesetzt. Sie müssen anschließend entweder manuell in das übergeordnete Verzeichnis zurückkehren:

    cd $i/*/; mv * ../; cd ../../
    

    oder verwenden Sie eine „Subshell“, um den Verzeichniswechsel einzuschränken:

    (cd $i/*/; mv * ../)
    
  3. Sie führen keine Fehlerprüfung durch. Wenn das cdjemals fehlschlägt, mvkann das Nachfolgende unangenehme Dinge tun. Verbinden Sie Befehle entweder mit &&oder führen Sie die entgegengesetzte Prüfung durch und verwenden Sie || exit(oder || break), je nachdem, was am besten aussieht:

    for i in */; do
        cd $i/*/ && {
            mv * ../;
            cd ../../
        }
    done
    
    for i in */; do
        cd $i/*/ || exit
        mv * ../
        cd ../../
    done
    
    for i in */; do
        (cd $i/*/ && mv * ../)
    done
    
  4. Verbesserung: Sie können den Unterverzeichnis-Platzhalter nach verschieben mv, sodass es auch funktioniert, wenn mehrere Unterverzeichnisse vorhanden sind:

    cd $i/ || exit
    mv */* .
    cd ../
    
  5. Verbesserung: Sie können dies tun, ohne Folgendes cdüberhaupt zu benötigen:

    mv $i/*/* $i/
    

verwandte Informationen