Befehlszeilen-MV-Ausschlussliste

11

Gibt es eine Möglichkeit zu mv, cpoder jede Dateioperation , so dass ich alle Dateien angeben konnte ich nicht wollen , betroffen?

Zum Beispiel, sagen , dass ich einen Ordner mit den Dateien haben file1, file2und file3, und ich möchte bewegen file1und file2irgendwo. Anstatt die zu verschiebenden Dateien explizit zu benennen ( mv file1 file2 /path/to/destination), möchte ich die nicht zu verschiebenden Dateien benennen und alle anderen im Ordner verschieben lassen ( mv --some-switch file3 /path/to/destination)

Gleiten
quelle
Ich glaube, das mv file1 file2 /path/to/destinationwird nicht das tun, was Sie wollen
phunehehe

Antworten:

19
  • Sie können die erweiterten Globbing-Muster in einigen Shells verwenden, um alle Dateien in einem Verzeichnis abzugleichen, mit Ausnahme derjenigen, die einem bestimmten Muster entsprechen. Zum Beispiel in ksh, bash oder zsh den Befehl

    shopt -s extglob   ## needed in bash only
    setopt ksh_glob   ## needed in zsh only
    mv /source/!(*.bak) /destination
    

    werden alle Dateien bewegen , /sourceum /destinationdie Dateien passende except *.bak. In zsh können Sie auch schreiben, /source/^*.bakwenn Sie das erste Mal ausführen setopt extended_glob, und allgemeiner (erneut erforderlich setopt extended_glob) /source/*~*.bak(oder /source/a*~*.bakfür alle Dateien, deren Name mit aAusnahme von .bakDateien usw. beginnt ).

  • Zsh verfügt über einen Massenbefehl zum Kopieren / Verschieben / Verknüpfen, mit dem unter anderem alle Dateien außer denen, die einem Muster entsprechen, verschoben werden können. Der folgende Befehl verschiebt beispielsweise alle Dateien außer *.bakvon /sourcenach targetund fügt .bakdabei ihren Namen hinzu :

    autoload zmv
    zmv '/source/(*)~*.bak' '/target/$1.bak'
    
  • Es gibt mehrere Befehle, die als renameFloating bezeichnet werden. Unter Debian und Ubuntu gibt /usr/bin/renamees ein Perl-Skript, das Dateien unter einem neuen Namen verschiebt, der durch einen Perl-Ausdruck generiert wird. Sie können Dateien vom Umbenennen ausschließen, indem Sie keinen neuen Namen generieren, wenn die Datei ausgeschlossen werden soll. Mit dem folgenden Befehl (mit diesem speziellen renameProgramm) werden beispielsweise alle Dateien außer *.bakvon /sourcenach verschoben /target:

    rename 's!/source!/target! unless m!\.bak$!' /source/*
    
  • Mit dem findBefehl können Sie die Dateien auswählen, die Sie verschieben möchten. Mit dem folgenden Befehl werden beispielsweise alle regulären Dateien außer *.bakin /sourceoder einem Unterverzeichnis in verschoben /target(beachten Sie, dass die Verzeichnisstruktur reduziert ist):

    find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
    

    oder (effizienter, wenn viele Dateien verschoben werden müssen)

    find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
    
  • rsyncist eine Verallgemeinerung von cpund scpmit sehr mächtigen Einschluss- / Ausschlussregeln. Mit dem folgenden Befehl werden beispielsweise alle Dateien außer *.bakin /sourceoder einem Unterverzeichnis /targetunter Berücksichtigung der Verzeichnisstruktur kopiert :

    rsync -a --exclude '*.bak' /source/ /target/
    
  • paxist (unter anderem) eine andere cpauf Steroiden. Die Ausschlussregeln sind bei weitem nicht so leistungsfähig wie die von rsync, bieten jedoch die Möglichkeit, Dateien beim Kopieren umzubenennen. Wenn Sie eine Datei in die leere Zeichenfolge umbenennen, wird sie von der Kopie ausgeschlossen. Mit dem folgenden Befehl werden beispielsweise alle Dateien außer *.bakin /sourceoder einem Unterverzeichnis in kopiert /targetund die Dateien .bakim Vorbeigehen in umbenannt.

    cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
    

    Das obige Beispiel hat den unglücklichen Nebeneffekt, dass Verzeichnisse aufgerufen werden foo.bak, die durch die Kombination findmit pax:

    { cd /source && find . -type f; } | \
    pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
    
Gilles 'SO - hör auf böse zu sein'
quelle
Genial. Eine mögliche Korrektur: Ich denke, dass der findBefehl in enden muss\;
Steven D
@Steven: Danke, ich vergesse immer wieder, dass du nur +unmittelbar danach verwenden kannst {}.
Gilles 'SO - hör auf böse zu sein'
schöne Liste, danke dafür. :-)
Echox
1
Was für eine Antwort, große Daumen hoch :)
Dzung Nguyen