Frage Linux (mv oder cp) spezifische Dateien aus einer Textliste von Dateien?


Ich habe ein Verzeichnis mit vielen Dateien, etwa 50.000 PDFs und anderen Dateien auf einem Server. Ich muss bestimmte in ein anderes Verzeichnis verschieben. Ich kann eine Liste der Dateien erzeugen, die entweder in CSV oder einem anderen Textformat verschoben werden müssen.

Was ich tun muss, ist ein Bash-Skript ausführen und verschieben oder kopieren Sie die Dateien, die in der Textdatei aufgeführt sind, in ein anderes Verzeichnis.

Gibt es eine einfache Möglichkeit, dies zu tun? Irgendwelche Vorschläge oder Betriebsmittel würden sehr geschätzt.


28
2017-12-14 14:07


Ursprung


Außerdem werden die Dateien nach dem Zufallsprinzip benannt, wenn sie dem Verzeichnis hinzugefügt werden. Es gibt keine Namenskonvention oder Logik, die zum Verschieben bestimmter Dateien verwendet werden könnte. - Jestep


Antworten:


rsync hat mehrere Optionen, die eine Liste von Dateien verarbeiten können (--files-from, --include-from, usw.).


20
2017-12-14 14:15





Um einen nutzlosen Gebrauch von zu vermeiden cat (und wenn Sie nicht verwenden rsync):

xargs -a file_list.txt mv -t /path/to/dest

Dies wird mit jedem gültigen Dateinamen umgehen, es sei denn, es enthält einen Zeilenumbruch, wenn die Dateien einen pro Zeile enthalten.


22
2017-12-14 15:02



Ein Nachteil dieses Ansatzes besteht darin, dass, wenn die Dateien in der Liste Pfadnamen enthalten (d. H. Sie befinden sich nicht alle im selben Verzeichnis), die Verwendung von mv wird alle von ihnen in dasselbe Zielverzeichnis einklappen. Das rsync Ansatz in der akzeptierten Antwort leidet nicht unter dieser Einschränkung. - Jason R
Außerdem habe ich diesen Befehl ausprobiert und XARGs würde alle Dateien, die ein einzelnes Zitat enthalten ("unübertroffenes einfaches Anführungszeichen") brechen - James Beninger
Das funktionierte für mich, weil ich eigentlich die Dateien aus verschiedenen Quellpfaden im selben Zielverzeichnis haben wollte. - PseudoNoise


for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

Bash vorausgesetzt, plus listoffiles enthält eine Datei pro Zeile. Mein einziger Einwand gegen die Rsync-Route ist, dass das OP nach einer Methode fragt, die Dateien zu verschieben und nicht zu kopieren. rsync hat mehr Flags als eine königliche Hochzeit, also bin ich mir sicher, dass es weiter modifiziert werden kann, um das zu tun, aber manchmal einfacher ist besser!


15
2017-12-14 15:12



Diese Lösung erscheint mir als die flexibelste. Ich habe es am Ende mit rsync anstelle von cp oder mv verwendet, nur weil ich die relative Dateipfade Option brauchte. - Spamwich
Nett, nur hatte ich Probleme mit Leerzeichen, also änderte ich es zu: while read -r file; do mv "$file" /path/of/destination ; done < listoffiles - user1182474
@ user1182474 Danke, und eine elegante Verwendung der Eingabeumleitung. Die traditionelle Methode, die Zufriedenheit mit einer Antwort zu zeigen, ist nebenbei bemerkt, dass es eine Verbesserung gibt! - MadHatter
@ user1182474 danke dafür! Letzter Schritt in vielen Modifikationen musste etwas blind machen, um meine OSX-Backup-Utilities auf mein Android zu portieren! - Charlie Gorichanaz


Dies hängt vom Format der Textdatei ab, die Sie haben. Zum Beispiel, wenn Sie die Liste der Dateien so geschrieben haben, dass jede Datei in einer neuen Zeile steht. Sie können Xargs verwenden wie:

$ cat your_text_file | xargs cp -t /path/to/destination

Sie können auch verwenden find Befehl mit -exec Möglichkeit. um die Dateien zu kopieren / verschieben.


3
2017-12-14 14:35





Ich denke, die Rsync-Antwort ist eine bessere, aber nur für eine andere Option:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)

1
2017-12-14 14:26





Ich habe versehentlich den gesamten Inhalt eines Verzeichnisses in ein Zielverzeichnis kopiert, anstatt das vollständige Verzeichnis zu verschieben. Dies führte zu einem unordentlichen Zielverzeichnis anstelle des Ursprungsverzeichnisses, das dem Verzeichnis hinzugefügt wurde.

Um das zu beheben, habe ich Folgendes getan:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove Der obige Befehl erstellt die filestomove-Datei, die eine Liste aller Inhalte des Zielverzeichnisses darstellt, rückwärts sortiert nach Zeit, dh von Ältesten bis Neuesten.

Dann habe ich ein Unterverzeichnis des jetzt überladenen Zielverzeichnisses erstellt, in das das Zeug hineingeschoben werden soll.

mkdir /path/to/cluttered/destination/directory/newsubdirectory

Dann habe ich die Verzeichnisliste wiederholt, außer auf dem Bildschirm zu erscheinen und weitere Details anzuzeigen.

ls -lrht /path/to/cluttered/destination/directory/ Diese Zeile listet das Verzeichnis auf, sortiert nach Datum aufsteigend (umgekehrte Sortierung nach Zeit) und zeigt weitere Informationen an, einschließlich des Datums- / Zeitstempels jeder Datei im nun überfüllten Zielverzeichnis. Ich beziehe mich darauf, beginnend an der Spitze, um zu zeigen, welche Verzeichnisse und Dateien ich behalten möchte, wo sie waren. Es wird eine Lücke im Datums- / Zeitstempel der Dateien geben, in denen alle neuen Dateien beginnen, die nicht dort sein sollten.

Dann habe ich die Datei fomestomove bearbeitet, die im ersten Schritt oben erstellt wurde (die nach Datum sortiert ist) und die wenigen Dateien aus der Liste gelöscht, die vorher dort waren, wo ich aus dem ursprünglichen Verzeichnis bleiben möchte.

vim /opt/dircheck/filestomove       Löschen Sie von oben alle Dateien, die Sie nicht verschieben möchten.

Dann habe ich den Befehl verwendet, der zuvor in diesem Beitrag aufgeführt wurde, um die Dateien in meiner Liste in das neue Verzeichnis zu verschieben, das ich erstellt habe.

sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

Dadurch wurden alle Dateien im Bruchteil einer Sekunde verschoben. (Hinweis: Sie brauchen das sudo möglicherweise nicht am Anfang, dies ist eine Frage der Dateiberechtigungen).

Jetzt ist mein ursprüngliches Zielverzeichnis schön und sauber und enthält ein neues Verzeichnis mit allen Dateien und Verzeichnissen, die es überflutet haben.


1
2017-12-07 04:26





rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync hat den zusätzlichen Vorteil gegenüber dem cp oder mv Befehle, da automatisch Ordner erstellt werden, wenn sie nicht vorhanden sind.


1
2017-09-17 19:02



Warum ist /path/to/source benötigt, wenn es die Pfade aus der Dateiliste nimmt? - bzero


Wenn (und nur wenn), haben Sie keine fiesen Zeichen in den Dateinamen (Leerzeichen, Zeilenumbrüche, die Xargs verwechseln würden, wie man Dinge in einzelne Argumente aufteilt) und Sie erzeugen eine Liste von Dateien, die durch Zeilenumbrüche getrennt sind (eine Datei) pro Zeile), könnten Sie etwas tun.

cat filenames.txt | xargs mv -t /path/to/move/files/to

(Im Allgemeinen, siehe Mann xargs, Es ist toll)

Wenn dein spezielles mv nicht die Option -t hat, könntest du auch einige Tricks machen

( cat filenames.txt; echo /path/to/move/files/to ) | xargs mv

0
2017-12-14 14:16



Jedoch; Sehen Sie Ignacios Antwort, Rsync ist für dieses Zeug gemacht. - Kjetil Joergensen


Versuchen Sie etwas wie:

cat list.txt | while read line; do mv "$line" /images; done

0
2017-12-14 14:16



hätte sein können while read line; do mv $line /images; done < list.txt  als ein einziger Befehl - ignivs