Wie schließe ich eine bestimmte Erweiterung vom rekursiven Dateikopieren aus?

Wie schließe ich eine bestimmte Erweiterung vom rekursiven Dateikopieren aus?

Ich möchte alle Dateien und Unterverzeichnisse außer der Datendatei mit dem Namen *.data in ein Zielverzeichnis kopieren.

 [ichen@ui01 sub_test]$ ls
a.cxx  a.data  subdir
[ichen@ui01 sub_test]$ ls subdir/
sub_a.cxx  sub_a.data

Wie Sie sehen, befinden sich im Außenverzeichnis bzw. im Unterverzeichnis zwei Datendateien. Ich habe diesen Befehl verwendet:

[ichen@ui01 sub_test]$ cp -r !(*.data) ../destination_dir/

zielte darauf ab, alle Dateien außer den *.data zum Ziel zu kopieren, aber es funktionierte nicht im Unterverzeichnis:

  [ichen@ui01 destination_dir]$ ls
a.cxx  subdir
[ichen@ui01 destination_dir]$ ls subdir/
sub_a.cxx  sub_a.data

Oben können Sie sehen, dass dieser Befehl nur im ersten Verzeichnis funktioniert. Wie kann ich dafür sorgen, dass er in allen Unterverzeichnissen funktioniert?

Antwort1

Sie geben in Ihrer Frage nicht an, ob die Verzeichnisstruktur in der Kopie beibehalten werden muss oder ob Sie nur eine Kopie der Dateien benötigen. Um einfach alle Dateien zu kopieren, die nicht den Namen *.data haben, können Sie Folgendes verwenden:

find . -type f ! -name '*.data' | xargs cp -t ../destination_dir/

Wenn Sie andererseits die Verzeichnisstruktur beibehalten möchten, können Sie etwa Folgendes verwenden:

for file in `find . ! -name '*.txt' | sed 's/^.\///'`; do if [ -d "./$file" ]; then mkdir -p "../destination_dir/$file"; else cp "./$file" "../destination_dir/$file"; fi; done

Ich bin nicht sicher, ob es einen einfacheren Weg gibt, dies zu tun, aber dieser Befehl bewirkt Folgendes:

Suchen Sie alle Dateien und Ordner im aktuellen Verzeichnis oder seinen Unterordnern, die nicht mit *.data übereinstimmen, und führen Sie dann für jeden Folgendes aus:

Testen Sie, ob es sich bei der Datei um ein Verzeichnis handelt, und erstellen Sie unter dem Zielverzeichnis ein passendes Verzeichnis. Wenn es sich um eine Datei handelt, wird diese stattdessen in das Ziel kopiert.

Bearbeiten: Shell-Skriptversion hinzufügen:

#!/bin/bash

# Disable shell glob expansion within the script
# Required to stop bash from expndinging the glob in $1
set -f

for file in `find . ! -name $1 | sed 's/^.\///'`
  do if [ -d "./$file" ]; then
    mkdir -p "$2/$file"
  else
    cp "./$file" "$2/$file"
fi
done

verwandte Informationen