BASH kopiuje wszystkie pliki oprócz jednego

110

Chciałbym skopiować wszystkie pliki z katalogu poza jednym o nazwie Default.png. Wydaje się, że można to zrobić na kilka sposobów. Co wydaje Ci się najbardziej skuteczne?

Joe Cannatti
źródło
Dlaczego potrzebujesz go do pominięcia tego pliku, a nie po prostu usuwania go po skopiowaniu? Czy istnieje już w katalogu docelowym?
Lasse V. Karlsen
1
Tak, plik o tej samej nazwie już istnieje w docelowym katalogu.
Joe Cannatti
@ LasseV.Karlsen: Lub możesz chcieć zaoszczędzić czas kopiowania, jeśli jest to duży plik. Interesuje mnie to, ale wykluczam raczej katalog niż plik.
Nikana Reklawyks

Odpowiedzi:

54

Proste, jeśli src/zawiera tylko pliki:

find src/ ! -name Default.png -exec cp -t dest/ {} +

Jeśli src/ma podkatalogi, pomija je, ale kopiuje pliki w nich:

find src/ -type f ! -name Default.png -exec cp -t dest/ {} +

Jeśli src/ma podkatalogi, to się do nich nie powtarza:

find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +
John Kugelman
źródło
5
Okazuje się, że jest to najlepsze dla mnie, ponieważ wydaje się, że OS X jest dostarczany bez włączonego globu.
Joe Cannatti
6
@Max \;wykonuje polecenie raz na plik. +uruchamia polecenie raz i przekazuje do niego wszystkie nazwy plików naraz (z zastrzeżeniem limitu długości wiersza polecenia). +jest ogólnie bardziej wydajna.
John Kugelman,
149

Powinien wyglądać następująco:

cp -r !(Default.png) /dest

Jeśli kopiujesz do folderu zagnieżdżonego w bieżącym folderze (nazywanym przykładem w poniższym przypadku), musisz również pominąć ten katalog:

cp -r !(Default.png|example) /example
Jon
źródło
17
To daje -bash:!: Event not found
Joe Cannatti
Czy kopiujesz pliki do folderu zagnieżdżonego w folderze, z którego kopiujesz?
Jon
47
Wymaga shopt -s extglobto pracy, jeśli zostało wyłączone.
Barry Kelly
5
Wygląda na to, że OS X musi być używany shopt -s extglobzgodnie z opisem @BarryKelly. Dzięki temu działa idealnie.
Kat,
Lat na Bash i nie wiedziałem o !()... Pięknym! Dla tych, którzy - podobnie jak ja - czują, że nadszedł czas, aby przestudiować / przejrzeć bash , oto odpowiednie linki związane z tym pytaniem / odpowiedzią: shopt / extglob i wzór .
Brandt
73

rsync był moim zamiennikiem cp / scp przez długi czas:

rsync -av from/ to/ --exclude=Default.png

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose               increase verbosity
matja
źródło
Jeśli chcę wykluczyć dwa różne pliki, jak tego użyć?
Pulkit Bansal
obsługiwanych jest wiele argumentów --exclude =. I nie zapomnij o -rargumencie, jeśli synchronizujesz katalogi
Rian Sanderson,
5

Po prostu zrobiłbym:

cp srcdir/* destdir/ ; rm destdir/Default.png

chyba że pliki są duże. W przeciwnym razie użyj np

find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
nr
źródło
1
Pierwsza komenda nie jest tym, o co prosił OP. Jeśli Default.pngistnieje w dwóch katalogach, zastąpi ten w destdirjednym w srcdir, a następnie usunie skopiowany plik Default.png. Zamiast tego OP chce zachować to, Default.pngco już istnieje w destdir.
SnowFrog
2
co powiesz na default.png już istnieje w destdir? Twoje rozwiązanie nie zadziała.
Iman Mohamadi
2

Działa to świetnie do kopiowania wszystkiego oprócz modułów węzłów :) Ciesz się i dzięki powyższym odpowiedziom właśnie do tego dodałem. Rsync jest moim zdaniem lepszy niż CP, ponieważ możesz zobaczyć pasek postępu bez pytania o to.

   rsync -av fromDirectory/ ToDirectory/ --exclude=node_modules
Josh
źródło
0
cp `ls | grep -v Default.png` destdir
Will Hartung
źródło
5
Jest to bardziej prawdopodobne, że spowoduje to błędy, niż zrobienie tego, co zamierzasz.
Wstrzymano do odwołania.
-1
# chattr +i /files_to_exclude
# cp source destination
# chattr -i /files_to_exclude
Ivan Grynenko
źródło
-2

użyj parametru rozszerzającego powłoki z wyrażeniem regularnym

cp /<path>/[^not_to_copy_file]* .

Wszystko zostanie skopiowane z wyjątkiem pliku not_to_copy_file

- jeśli coś jest z tym nie tak. proszę sprecyzuj !

Alex
źródło
1
Witamy w SO. Niestety twoja odpowiedź jest nieprawidłowa. Wyrażenie nawiasu ( [...]) zawiera zestaw znaków do dopasowania, podczas gdy początkowy ^spowoduje dopasowanie dopełnienia wymienionych znaków. W poniższym przykładzie, ani plik zostanie wymienione: touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*ponieważ wszystkie nazwy plików rozpoczynające się z którymkolwiek z następujących znaków zostaną wyłączone: _cefilnopty.
rtx13