Wie gehe ich rekursiv durch Verzeichnisse und benenne eine Datei nach dem Verzeichnis?

0

Ich versuche, alle Dateien in einem Unterverzeichnis zu einer neuen Datei zu kombinieren und der neuen kombinierten Datei den gleichen Namen wie dem Unterverzeichnis zu geben. Ich habe keine Ahnung, wie dies in Bash geschehen soll. Hier ist, wie ich es angegangen bin: Ich habe eine Reihe von Verzeichnissen, jedes mit einem eindeutigen Dateinamen (mit Leerzeichen!). In jedem dieser Verzeichnisse gibt es eine Reihe von Dateien mit numerischen Namen, wie zum Beispiel:

Home/Unique name/1.pdf  
Home/Unique name/2.pdf  
Home/Unique name/3.pdf  
Home/Unique name/4.pdf  
....  
Home/Other Unique name/1.pdf  
Home/Other Unique name/2.pdf  
Home/Other Unique name/3.pdf  
Home/Other Unique name/4.pdf

Was ich tun möchte, ist ein Bash-Skript (aus dem HomeVerzeichnis) zu schreiben :

  1. Gehen Sie in jedes eindeutige Verzeichnis und führen Sie einen Befehl für jede der Dateien in diesem Verzeichnis aus (in meinem Fall kopieren Sie sie alle in ein anderes Verzeichnis).
  2. Ich habe dann ein anderes Skript geschrieben script.sh, das einen anderen Befehl ausführt (in diesem Fall kombinieren Sie alle PDFs in einer einzigen Datei temp.pdf). Ich möchte dann diese temp.pdfDatei nach dem Verzeichnis umbenennen Unique name.pdf(mit Leerzeichen).
  3. Ich muss diesen Prozess für eine Reihe von Unterverzeichnissen folgen.

Ich habe versucht, eine Lösung mit einer Reihe von for-Schleifen, while-Schleifen und dem Befehl find zu finden, aber ich bin mit bash nicht vertraut genug, um komfortabel zu debuggen oder diese Variablen mit einem gewissen Maß an Sicherheit zu verwenden. Ich bin mir auch sicher, dass es eine effizientere Möglichkeit gibt, das zu tun, was ich tue, aber ich habe das Skript über einen bestimmten Zeitraum hinweg zusammengebastelt.

Marc
quelle
Sollte ein relativ einfaches C- oder Java-Programm sein.
Daniel R Hicks
Sofern Sie dies für Klartext - kodierte Dateien tun, werden die resultierenden Dateien nicht als gültig betrachtet werden. Wenn Sie beispielsweise nur die Binärdaten in einigen PDF-Dateien verketten, ist die resultierende Datei keine PDF-kompatible Datei (wenn Sie Glück haben, wird möglicherweise nur die erste PDF-Datei angezeigt). Sie benötigen ein bestimmtes Tool für das Format der Dateien, die Sie verbinden möchten. Wenn Sie jedoch mehrere Dateien verbinden möchten, können Sie sie einfach catin der richtigen Reihenfolge anzeigen und die Ergebnisse catin eine neue Datei umleiten.
Durchbruch
@DanielRHicks für etwas dieses einfache Verwendung von C wäre urkomisch Overkill
evilsoup

Antworten:

1

Die POSIX-Methode ist zu verwenden print . -type d ... | while read f; do, aber wenn Sie nicht von 100% Portabilität besessen sind, würde ich mich nicht darum kümmern. Wenn Sie Bash 4+ und pdfunite(standardmäßig auf meinem Ubuntu 13.04 installiert) haben, können Sie dies in zwei Zeilen tun:

shopt -s globstar
for f in ./**/; do pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Beachten Sie, dass shopt -s globstarsich dies in einer separaten Zeile zum Rest befinden muss. Wird bei aktiviertem Globstar **rekursiv auf alle Dateien und Verzeichnisse im aktuellen Verzeichnis erweitert. Da Dateien nicht /in ihren Namen enthalten sein können, **/werden nur die Verzeichnisse erweitert. Ich verwende ./**/in dem unwahrscheinlichen Fall, dass Ihre Verzeichnisse mit einem Bindestrich ( -) beginnen, da dies Probleme verursachen kann, da viele Programme alles, was mit einem beginnt, -als Option behandeln.

Wie geschrieben, werden die PDFs nicht in ein anderes Verzeichnis kopiert, aber das ist ziemlich trivial hinzuzufügen:

for f in ./**/; do cp "$f"/*.pdf /target/dir/; pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"; done

Wenn Sie Ihr eigenes benutzerdefiniertes PDF-Kombinationsskript verwenden möchten, ändern Sie einfach die Zeile entsprechend. Beachten Sie jedoch, dass beim Erstellen von Shell-Skripten bereits vorhandene Befehle zusammengestellt werden.

Hier ist eine etwas portablere Version:

print . -type d -print0 | while read -d $'\0' f; do
  pdfunite "$f"/*.pdf "$f"/"$(basename "$f").pdf"
done
Übelsuppe
quelle
0
  1. Erstellen Sie eine forSchleife mit find /home/ -type f -name "*.pdf"als Variable
  2. Kopieren Sie die Dateien dorthin, wo Sie sie benötigen, nehmen Sie $ VARIABLE und verarbeiten Sie es durch sed / awk, um "/" zu entfernen.

Veröffentlichen Sie Ihr Skript und wir können Ihnen helfen, es zu verbessern.

Sie können Skripts immer mit ausführen bash -x, um sie zu debuggen, oder Sie können festlegen !#/bin/bash -x, dass sie immer im Debug-Modus (ausführlich) ausgeführt werden.

Chris
quelle