Das ist wahrscheinlich sehr einfach, aber ich kann es nicht herausfinden. Ich habe eine Verzeichnisstruktur wie folgt (dir2 ist in dir1):
/dir1
/dir2
|
--- file1
|
--- file2
Was ist der beste Weg, um diese Director-Struktur so zu reduzieren, dass file1 und file2 in dir1 und nicht in dir2 abgelegt werden.
Antworten:
Sie können dies mit GNU
find
und GNU tunmv
:Grundsätzlich funktioniert dies, wenn
find
der gesamte Verzeichnisbaum durchlaufen wird und für jede Datei (-type f
), die sich nicht im obersten Verzeichnis befindet (-mindepth 2
), ein ausgeführt wirdmv
, um sie in das gewünschte Verzeichnis zu verschieben (-exec mv … +
). Das-t
Argument,mv
mit dem Sie zuerst das Zielverzeichnis angeben können, das erforderlich ist, da bei der+
Form von-exec
alle Quellspeicherorte am Ende des Befehls stehen. Die-i
Markenmv
fragen vor dem Überschreiben alle Duplikate ab; Sie können ersetzen-f
, um sie zu überschreiben, ohne zu fragen (oder-n
nicht zu fragen oder zu überschreiben).Wie Stephane Chazelas betont, funktioniert das Obige nur mit GNU-Tools (die unter Linux Standard sind, aber nicht mit den meisten anderen Systemen). Das Folgende ist etwas langsamer (weil es
mv
mehrfach aufgerufen wird), aber viel universeller:quelle
-exec +
so dass es keine große Anzahl von Prozessen vonmv
mv
benötigt das Ziel als letztes Argument, aber + würde die Quellen als letztes Argument haben. Find akzeptiert nicht einmal die von Ihnen geänderte Syntax zu (find: missing argument to `-exec'
)mv
hat ein-t
wir verwenden können, so werde ich es ändern.find
druckt standardmäßig versteckte (Punkt-) Dateien. Die Tiefe ist relativ zu dem Verzeichnis, das Sie suchen.find ./dir -mindepth 2 -type f -exec mv -f '{}' ./dir ';'
wenn Duplikate überschrieben werdenIn zsh:
**/
Durchläuft Unterverzeichnisse rekursiv. Das Glob-Qualifikationsmerkmal.
stimmt nur mit regulären Dateien überein undD
stellt sicher, dass Punktdateien enthalten sind (standardmäßig werden Dateien, deren Name mit einem beginnt.
, von Platzhalterübereinstimmungen ausgeschlossen). Um jetzt leere Verzeichnisse anschließend zu bereinigen, führen Siermdir dir1/**/*(/Dod)
- aus und/
beschränken Sie sich auf Verzeichnisse.od
Ordnen Sie die Übereinstimmungstiefe zuerst an, um siedir1/dir2/dir3
vorher zu entfernendir1/dir2
.Wenn die Gesamtlänge der Dateinamen sehr groß ist, kann die Befehlszeilenlänge eingeschränkt sein. Zsh verfügt über integrierte Funktionen für
mv
undrmdir
die von dieser Einschränkung nicht betroffen sind: Führen Sie diese auszmodload zsh/files
, um sie zu aktivieren.Nur mit POSIX-Tools:
oder (schneller, weil nicht für jede Datei ein separater Prozess ausgeführt werden muss)
quelle
Versuchen Sie Folgendes:
oder für jede passende Datei
file[0-9]*
im Unterverzeichnis:Siehe http://mywiki.wooledge.org/glob
quelle
{}
in meinem eigentlichen Problem zu verwenden.Ich habe zwei Funktionen geschrieben, die Sie zusammen verwenden können, um genau das zu erreichen. Sie können die Verzeichnisebene einschränken, indem Sie einen
-maxdepth $VAL
Parameter hinzufügen .quelle
Erweitern Sie die beliebte Antwort auf diese Frage, da ich einen Anwendungsfall zum Reduzieren eines Verzeichnisses mit gleichnamigen Dateien hatte.
In diesem Fall würde die übergebene Option
-i
(--interactive
)mv
nicht das gewünschte Ergebnis liefern, um die Verzeichnisstruktur zu reduzieren und Namenskonflikte zu behandeln. Es wird also einfach durch--backup=t
(äquivalent zu--backup=numbered
) ersetzt. Weitere Dokumentation zur Option-b
(--backup
) finden Sie unter https://www.gnu.org/software/coreutils/manual/coreutils.html#Backup-options .Ergebend:
Welche Erträge:
quelle
Sowohl tar als auch zip haben die Möglichkeit, eine Verzeichnisstruktur zu integrieren und dann zu entfernen, sodass ich ein verschachteltes Verzeichnis mit schnell reduzieren konnte
tar -cvf all.tar *
Anschließend verschieben Sie all.tar an einen neuen Speicherort
tar -xvf all.tar --strip=4
quelle