Verschieben Sie eine Gruppe von Dateien und fordern Sie den Benutzer zur Bestätigung für jede Datei auf

9

System: Ubuntu MATE 18.04.

Ich habe eine Sammlung von Dateien (in mehreren Verzeichnissen in einer Verzeichnisstruktur) und möchte viele davon in ein anderes Verzeichnis verschieben. Ich kann anhand ihrer Namen erkennen, welche Dateien ich verschieben möchte (es handelt sich um Rezepttitel), aber es gibt keine andere Möglichkeit, zwischen Dateien, die ich verschieben möchte, und Dateien, die ich nicht verschieben möchte, zu unterscheiden. Ich muss für jede Datei eine Entscheidung treffen, indem ich den Namen selbst überprüfe.

Ich führe also einmal einen Befehl für jede Datei aus, die ich verschieben möchte

mv Snacks/OkaraCrackers NeedsTesting/
mv Snacks/SunflowerBrittle NeedsTesting/
mv Treats/ChocolateChilliFudge NeedsTesting/
mv Treats/PecanBlondies NeedsTesting/

Selbst mit Tab-Vervollständigung ist dies zu viel Eingabe. Was ich wirklich tun möchte, ist so etwas wie

shopt -s globstar
mv --prompt-me-for-every-file ** NeedsTesting/

Also kann ich einfach yoder nfür jede Datei drücken .

Wie kann ich eine Gruppe von Dateien verschieben und für jede Datei zur Bestätigung aufgefordert werden?

Zanna
quelle

Antworten:

6

Weg 1: In Ihrem grafischen Dateibrowser mithilfe einer Baumansicht

Ich gehe davon aus, dass Ihr eigentliches Ziel darin besteht, für jede Datei eine Auswahl zu treffen und nicht unbedingt dazu aufgefordert zu werden . Wenn Sie jedoch lieber zu jeder Datei in einem Terminal aufgefordert werden möchten, lesen Sie den folgenden Weg 2.

Die meisten Browser für grafische Dateien unterstützen eine Baumansicht, in der Sie mehrere Ebenen einer Verzeichnishierarchie zusammen anzeigen können. Sie können Dateien aus dieser Ansicht kopieren oder verschieben, entweder einzeln oder indem Sie sie auswählen und dann die gesamte Auswahl bearbeiten. Dies funktioniert auch mit Dateien aus mehreren Ordnern.

In einigen Dateibrowsern muss man in ein Einstellungsmenü gehen, um die Baumansicht zu aktivieren. In Caja, dem MATE-Dateibrowser, ist er in der Listenansicht immer aktiviert. Klicken Sie auf Ansicht → Liste (oder drücken Sie Ctrl+ 2), um zur Listenansicht zu wechseln. Jedes Verzeichnis hat links davon ein kleines nach rechts gerichtetes Dreieck, das angibt, dass es erweitert werden kann. Um einen Ordner zu erweitern, klicken Sie auf dieses Dreieck oder drücken Sie die Taste (Pfeil nach rechts), wenn der Ordner ausgewählt ist. In diesem Beispiel habe ich sie alle einzeln ausgewählt und ziehe sie alle gleichzeitig auf einmal an ihr Ziel:

Mehrere Dateien, die in einer Baumstruktur im Caja-Dateibrowser ausgewählt wurden, werden in einen anderen Ordner gezogen, aber noch nicht verschoben

Angenommen, Quelle und Ziel befinden sich auf demselben Laufwerk, werden standardmäßig Ziehbewegungen ausgeführt. Wenn Sie stattdessen kopieren möchten, halten Sie die CtrlTaste gedrückt.

Die Situation nach Abschluss des Ziehens, in der die ausgewählten Dateien jetzt alle zusammen im Zielordner anstatt an ihren ursprünglichen separaten Speicherorten gespeichert sind

Theoretisch ist es einfach, Fehler mit dieser Methode zu beheben, da die meisten Dateibrowser (einschließlich Caja) Ctrl+ unterstützen Z, um aktuelle Aktionen, einschließlich Stapelaktionen, rückgängig zu machen. Ich hatte jedoch gemischtes Glück damit. Manchmal werden Dateien wieder in den falschen Ordner verschoben.

Die gute Nachricht ist, dass Sie anscheinend hauptsächlich mit Textdokumenten arbeiten, die in der Regel klein sind, sodass Sie tarzunächst ohne großen Aufwand ein zusätzliches Backup erstellen können . Ich schlage vor, dies unabhängig von der verwendeten Methode zu tun.

Weg 2 : Der findBefehl mit der -okAktion

Es ist üblich find, Dateien zu finden und ihre Pfade mit den Aktionen -execund an einen beliebigen externen Befehl zu übergeben -execdir. Hat aber findauch -okund -okdirdiese Eingabeaufforderung vor jedem Ausführen eines Befehls. Wenn Sie wirklich in einem Terminal zu jeder Datei aufgefordert werden möchten, ist dies meiner Meinung nach der richtige Weg.

Wenn Sie die gleichen Effekte wie oben gezeigt erzielen, sieht das folgendermaßen aus:

ek@Gnar:~$ find Texts -xtype f -ok mv -t 'Glorious Destination Folder' {} \;
< mv ... Texts/Robert Frost/New Hampshire.pdf > ? y
< mv ... Texts/Robert Frost/In The Clearing.pdf > ? n
< mv ... Texts/Helen Keller/The Story of My Life.pdf > ? y
< mv ... Texts/Saki/The Short Stories of Saki.pdf > ? y
< mv ... Texts/Jane Austen/Sense and Sensibility.pdf > ? n
< mv ... Texts/Jane Austen/Pride and Prejudice.pdf > ? y
< mv ... Texts/Richard Connell/The Stolen Crime.pdf > ? n
< mv ... Texts/Richard Connell/The Most Dangerous Game.txt > ? y
< mv ... Texts/Mary Wollstonecraft Shelley/Mathilda.epub > ? n
< mv ... Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf > ? y
< mv ... Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf > ? n
< mv ... Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm > ? y

Ersetzen Sie Textsdurch das Quellverzeichnis (das nur sein könnte, .wenn Sie es möchten cd) und Glorious Destination Folderdurch das tatsächliche Zielverzeichnis.

Dadurch wird ein Befehl pro Datei ausgeführt. Im Gegensatz , -execund -execdir, -okund -okdirunterstützt nicht +anstelle von \;mehreren Pfade GEFUNDEN im gleichen Aufruf eines Befehls zu übergeben. Folglich müssen Sie nicht brauchen , die verwenden -t destForm mv. Ich schlage vor , dabei trotzdem, obwohl beide im Allgemeinen mit findund vor allem in dieser Situation , so dass die Anweisungen , mehr wie die nachgucken sie auffordert , über.

Wenn dieser Befehl beim Schreiben findauf einen symbolischen Link stößt, der letztendlich auf eine reguläre Datei verweist, wird er (der Link, nicht das Ziel) verschoben und nicht ignoriert. Wenn Sie wirklich nur eine reguläre Datei betreiben möchten, verwenden Sie -type fstattdessen -xtype f.

Möglicherweise möchten Sie dies in einer scriptSitzung tun, um herauszufinden, was passiert ist, wenn Sie einen Fehler machen. Aber auch hier kein Grund, kein Backup zu haben.

Weg 3: Generieren Sie ein Manifest und bearbeiten Sie es

Zumindest solange die Dateien keine Zeilenumbrüche enthalten, können Sie zunächst mit einem einfachen findBefehl ein Manifest erstellen - eine Datei, in der die Namen der Dateien aufgeführt sind, an denen Sie (in diesem Fall möglicherweise) interessiert sind ::

find Texts -xtype f >manifest

Ersetzen manifestSie die Datei, in der die betreffenden Dateien aufgeführt sind, durch einen beliebigen Namen (und passen Sie die verbleibenden Richtungen entsprechend an).

Ersetzen TextsSie wie oben durch Ihr eigentliches Quellverzeichnis. Dies könnte der Fall sein, .wenn Sie es getan cdhaben. Wenn Textses sich jedoch um einen relativen Pfad handelt (auch wenn dies der Fall ist .), sollten Sie sicherstellen, dass Sie sich später am selben Ort befinden, wenn Sie die Bewegungen tatsächlich ausführen.

findÖffnen Sie nach dem Ausführen dieses Befehls manifestin einem Texteditor. Dies könnte nano, vim, emacs, gedit, pluma, usw. Im Editor Kommentar aus den Zeilen , dass Namen Dateien , die Sie nicht , indem Sie eine verschieben mögen #am Anfang von ihnen. Einige Editoren heben diese Zeilen auch dann anders hervor, wenn sie nicht erkennen, dass Ihre Datei ein Format hat, von dem sie weiß, dass es Kommentare enthält. Die meisten werden dies jedoch nicht tun, und der wahre Grund, warum ich dies vorschlage, ist, dass Sie als Mensch wahrscheinlich Erfahrung mit dem Kommentieren von Zeilen in Konfigurationsdateien (und möglicherweise im Quellcode) haben. Ich denke , das ist intuitiver und weniger fehleranfällig, als es die Linien markieren würden Sie tun wollen , sich zu bewegen.

Natürlich können Sie stattdessen auch nur die Zeilen für Dateien löschen, die Sie nicht verschieben möchten. Der Vorteil des Kommentierens besteht darin, dass später klar wird, was Sie getan haben.

In meinem Beispiel sah der Inhalt der Datei nach der Bearbeitung folgendermaßen aus:

Texts/Robert Frost/New Hampshire.pdf
# Texts/Robert Frost/In The Clearing.pdf
Texts/Helen Keller/The Story of My Life.pdf
Texts/Saki/The Short Stories of Saki.pdf
# Texts/Jane Austen/Sense and Sensibility.pdf
Texts/Jane Austen/Pride and Prejudice.pdf
# Texts/Richard Connell/The Stolen Crime.pdf
Texts/Richard Connell/The Most Dangerous Game.txt
# Texts/Mary Wollstonecraft Shelley/Mathilda.epub
Texts/Mary Wollstonecraft Shelley/Frankenstein: Or, The Modern Prometheus.pdf
# Texts/W. E. B. Du Bois/The Souls of Black Folk.pdf
Texts/W. E. B. Du Bois/Darkwater: Voices from within the Veil.htm

Anschließend können Sie die kommentierten Zeilen mit herausfiltern grepund das Ergebnis xargsan folgende Adresse weiterleiten mv:

grep -Pv '^\s*#' manifest | xargs -d '\n' mv -t 'Glorious Destination Folder'

Ersetzen Sie wie oben durch Glorious Destination Folderden Namen des tatsächlichen Ziels. Das ist es; Ihre Dateien werden verschoben. Sie können natürlich echovorher schreiben mv, um die Befehle zu sehen, die zuerst ausgeführt werden, wenn Sie möchten.

Der Befehl funktioniert folgendermaßen:

  1. Der grepBefehl gibt Zeilen aus manifest, die nicht ( -v) start ( ^) mit optionalem ( *) Leerzeichen ( \s) gefolgt von einem Literalzeichen #. Das -PFlag wählt PCRE als Dialekt für reguläre Ausdrücke (was ermöglicht, \swas ich für lesbarer halte als das traditionelle [[:space:]]).
  2. Der xargsBefehl unterteilt seine Eingabe (die Ausgabe von grep) in Felder mit Zeilenumbruch ( -d '\n') und fügt dann jedes Feld (ohne den Zeilenumbruch) als separates Argument am Ende des Befehls ein mv -t 'Glorious Destination Folder', den er ausführt .
Eliah Kagan
quelle
1
-okIMHO die beste Antwort
pim
7

Hier ist ein kleines Skript ( mv-confirm.sh):

#!/bin/bash

# Just make sure there are at least one source and one destination
if [ "$#" -lt 2 ]; then
    echo "Illegal number of parameters"
fi

DESTINATION=${*:$#}             # last argument
SOURCES=( ${@:1:$#-1} )         # all but last arguments

for i in "${SOURCES[@]}"
do
    read -p "move '$i' to '$DESTINATION' ? [y/n] " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]
    then
        echo mv "$i" "$DESTINATION"
    fi
done

Beispielverwendung:

./mv-confirm.sh ** somewhere
move 'a' to 'somewhere' ? [y/n] n
move 'b' to 'somewhere' ? [y/n] y
mv b d
...

Vergessen Sie nicht, das Skript ausführbar zu machen ( chmod +x mv-confirm.sh).

NB

Da ich nicht mit Ihren Dateien herumspielen möchte, habe ich echovor dem eigentlichen mv Befehl hinzugefügt . Fühlen Sie sich frei, es zu entfernen, um die Dateien tatsächlich zu verschieben.

pim
quelle