Kopieren von Dateien mit bestimmten Namen in einen anderen Ordner

Kopieren von Dateien mit bestimmten Namen in einen anderen Ordner

Ich habe einen Ordner mit vielen Dateien. Ich möchte alle Dateien kopieren, die mit einem dieser Namen beginnen (durch Leerzeichen getrennt):

abc abd aer ab-x ate

in einen anderen Ordner. Wie kann ich das machen?

Antwort1

Mit csh, tcsh, ksh93, bash, fishoder zsh -o cshnullglobkönnen SieKlammererweiterungUndGlotzenum das zu tun ( --ist für diese Dateinamen nicht nötig, aber ich nehme an, dass es sich nur um Beispiele handelt):

cp -- {abc,abd,aer,ab-x,ate}* dest/

Wenn Sie die Klammererweiterung lieber nicht verwenden möchten, können Sie eine For-Schleife verwenden (hier Syntax im POSIX/Bourne-Stil):

for include in abc abd aer ab-x ate; do
    cp -- "$include"* dest/
done

Wenn Sie eine sehr große Anzahl von Dateien haben, kann dies aufgrund des cpeinmaligen Aufrufs pro Include langsam sein. Eine andere Möglichkeit wäre, ein Array zu füllen und von dort aus weiterzumachen (hier ksh93oder zshaktuelle bashSyntax):

files=()
includes=(abc abd aer ab-x ate)

for include in "${includes[@]}"; do
    files+=( "$include"* )
done

cp -- "${files[@]}" dest/        

Antwort2

Ein Hinweis zur Klammererweiterung im Vergleich zum Globbing.

Die Klammererweiterung ist kein Globbing (obwohl der Unterschied in csh/tcsh, wo sie ihren Ursprung hat, nicht so klar ist wie in anderen Shells). Sie wird durchgeführtVorGlobben.

Wenn Sie das also tun:

cp {a,b}* /dest

Es wird zunächst erweitert zu:

cp a* b* /dest

Das bedeutet, dass die Shell zwei Globs erweitern muss, also die vollständige Dateiliste zweimal abrufen und zweimal prüfen muss, welche dem Muster entsprechen.

Mit zshbedeutet dies auch, dass der gesamte Befehl abgebrochen wird, wenn einer der Globs mit keiner Datei übereinstimmt (Sie können dies umgehen, indem Sie die cshnullglobOption aktivieren, sich wie in csh zu verhalten).

Das bedeutet auch, dass Sie, wenn Sie

cp {a,ab}* /dest

cpkopiert die ab*Dateien zweimal.

Das ist etwas anderes als:

cp @(a|b)* /dest

von kshoder bash -O extgloboder zsh -o kshglob, oder

cp (a|b)* /dest

von zsh. Dort ist es nureinsglob, daher ist es effizienter und Dateien werden nur einmal eingefügt.

Mit zsh, wenn Sie die Liste der Präfixe in einem Array haben:

prefixes=(abc abd aer ab-x ate)
cp -- (${(j:|:)~prefixes})* /dest

(oben werden die Präfixe als Globs behandelt.) Das heißt, die Elemente des Arrays werden mit verknüpft |und das Ergebnis wird als Glob ( ~) betrachtet.

Wenn die Liste groß ist, kann es sein, dass die Ausführung cpmit einem„Argumentliste zu lang“Fehler. In diesem Fall können Sie zshdie integrierte Version verwenden, indem Sie das Modul ( ) cpladen .zsh/fileszmodload zsh/files

Antwort3

  1. Beispielsweise habe ich diese Dateien im aktuellen Verzeichnis:

    1-s2.0-S0038092X0000058X-main.pdf  ANNDHW.pdf     HPcalculation2
    1-s2.0-S0306261999000422-main.pdf  ANNlee.pdf     HPcalculation3
    ANNCanada.pdf                      HPcalculation  HPcalculation4
    
  2. Ich möchte alle Dateien beginnend mit HP in den Ordner verschieben:./NewFolder/

  3. Ich kann:

    cp ./HP* ./NewFolder/
    

    ./HP*teilt Linux mit, dass ich an allen Dateien interessiert bin, die mit HP beginnen. Umgekehrt gilt, wenn ich alle Dateien verschieben möchte, die mit enden .pdf. Ich kann *vor das setzen .pdf:

    cp ./*.pdf ./NewFolder/
    

Antwort4

Einfach können Sie tun

 cp abc* abd* aer* ab-x* ate*  DestinationPath

Eine Lösung für Ihr erweitertes Problem kann sein

  1. setze alle Dateinamen in eine Liste zB list0.txt
  2. Alles kopieren mit

    cp `cat list0.txt` DestinationPath # Benötigt keine Leerzeichen in den Dateinamen

    oder besser,

    während lesen -r Datei; mache cp "$file" dest/ ; fertig < list0.txt

Anmerkungen:

  • "$file", weil Sie so Namen mit Leerzeichen darin behandeln können alsOne Package.deb
  • -res schützt Sie vor Escape-Sequenzen.

    -r Backslash fungiert nicht als Escape-Zeichen. Der Backslash wird als Teil der Zeile betrachtet. Insbesondere darf ein Backslash-Newline-Paar nicht als Zeilenfortsetzung verwendet werden.

verwandte Informationen