Przenieś wszystkie pliki oprócz jednego


155

Jak mogę przenieść wszystkie pliki oprócz jednego? Szukam czegoś takiego:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

gdzie przenoszę stare rzeczy do nowego folderu z wyjątkiem Tux.png. ! -znak reprezentuje negację. Czy jest jakieś narzędzie do tej pracy?

Odpowiedzi:


142

Jeśli używasz basha i masz extglobustawioną opcję powłoki (co zwykle ma miejsce):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
Wystąpił błąd, gdy przetestowałem polecenie dla wielu pozycji: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Opróżnia cały stary katalog. Co jest nie tak?
— Léo Léopold Hertz 준영

5
@UnixBasics, spróbuj: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
— Juliano

@Juliano Bardzo fajne polecenie! Czy jest więcej operacji matematycznych, takich jak OR i XOR? Zakładam, że fajka jest dla AND.
— Léo Léopold Hertz 준영


@Juliano Jestem raczej zdezorientowany wzorcami takimi jak: mv ~ / Linux /? (Tux * .png) ~ / Linux / New / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / W pierwszym , Chciałem przenieść 0-1 Tux - zdjęcie. W tym drugim przypadku chciałem przenieść zdjęcia 1-n Tux. Poruszyli wszystko. Czemu? Czy można przenieść określoną ilość zdjęć?
— Léo Léopold Hertz 준영

97

Umieść następujący plik w swoim .bashrc

shopt -s extglob

Rozszerza wyrażenia regularne. Następnie możesz przenieść wszystkie pliki oprócz jednego o

mv !(fileOne) ~/path/newFolder

Wyjątki w stosunku do innych poleceń

Zauważ, że podczas kopiowania katalogów, forward-flash nie może być użyty w nazwie, jak zauważono w wątku. Dlaczego extglob oprócz łamania oprócz warunku? :

cp -r !(Backups.backupdb) /home/masi/Documents/

więc Backups.backupdb/jest źle tutaj przed negacją i nie użyłbym go również do przenoszenia katalogów ze względu na ryzyko niewłaściwego użycia then globs z innymi poleceniami i możliwymi innymi wyjątkami.


3
To jest właściwie prawidłowa odpowiedź. Mój był całkowicie zły; na szczęście użyłem go w folderze zawierającym tylko kilka plików. Tutaj jest więcej informacji o metodzie, którą pokazuje Masi: wiki.bash-hackers.org/syntax/pattern Przejdź do "Rozszerzony język wzorców", a znajdziesz więcej informacji na ten temat. Podziękowania dla @ paul-whittaker za wskazanie problemu.
— mimoralea

To stara odpowiedź, ale wciąż aktualna. Używam Ubuntu 18 i wydaje się, że extglob jest domyślnie włączony (nie kupowałem tego). Użyłem następującego polecenia, aby przenieść wszystkie pliki z bieżącego katalogu do archiwum, które również znajduje się w tym katalogu, BEZ innych folderów archiwum: mv !(arc*) archive_190629b
— TonyG

70

Wybrałbym tradycyjny sposób znajdowania i xargs:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1sprawia, że ​​nie przeszukuje rekurencyjnie. Jeśli zależy Ci tylko na plikach, możesz powiedzieć -type f. -mindepth 1sprawia, że ​​nie zawiera ~/Linux/Oldsamej ścieżki w wyniku. Działa z dowolnymi nazwami plików, w tym z tymi, które zawierają osadzone znaki nowej linii.

Jeden komentarz wskazuje, że -topcja mv jest prawdopodobnie rozszerzeniem GNU. W przypadku systemów, które go nie mają

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Za uznaniem, ponieważ zachęca do nauki potężnego narzędzia, znajdź. Uwaga, dla plików z białymi znakami to nie zadziała. Rozważ "find -print0 | xargs -0" albo zrezygnuj z xargs: "znajdź [co powiedziałeś] -exec mv -t {} ~ / Linux / New \;"
— JasonSmith

Jeśli twoje polecenie mv nie ma opcji -t, użyj "find ... -exec mv {} Linux / New \;" lub „find ... | xargs -I {} mv {} Linux / New”. Opcja -t wydaje się być rozszerzeniem GNU, które jest dobre dla Linuksa, ale prawdopodobnie nie gdzie indziej.
— Rob Kennedy

jhs, och, zawodzę. jakoś pomyślałem, że xargs dzieli się na nowej linii, ale nie na spacjach. wygląda na to, że pomyliłem to z „czytaj” :) źle to napraw
— Johannes Schaub - litb

Wielkie dzięki za niesamowitą wskazówkę! Miałem zamiar wybrać coś, ponieważ dotyczy tego pytania. Jednak później mogę wyczuć przydatność twoich poleceń, więc muszę wybrać sposób „znajdź i xargs”. Po prostu rządzi. Dzięki :)
— Léo Léopold Hertz 준영

Zbyt skomplikowane. Odpowiedź Masi jest bardziej kompletna, łatwiejsza, a tym samym bardziej poprawna
— user637338

30

Szybkim sposobem byłoby zmodyfikowanie nazwy pliku tux, aby polecenie ruchu nie pasowało.

Na przykład:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

nie używaj „ . ”, ponieważ spowoduje to przeniesienie tylko plików, które mają „.” w imieniu. Wystarczy „*”.
— Juliano

1
Jeśli zmienisz go na *, usunie to również plik, którego nazwa została zmieniona.
— John T

6
@John T: Nie, * glob nie pasuje do plików zaczynających się kropką.
— Bill Karwin

To zdecydowanie najlepsza odpowiedź. Nie musisz zmieniać ani komentować tej odpowiedzi. 100 punktów. Wielkie dzięki. Dobra robota!
— Steve K

23

Myślę, że najłatwiej to zrobić za pomocą graweru

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Edytować:

Zamiast tego użyj odwrotnego ukośnika z ls, aby zapobiec używaniu go z aliasem, np. Większość ls jest aliasowana jako ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Dzięki @Arnold Roa


1
Czy możesz wyjaśnić, dlaczego grep -vtam używasz ?
— Léo Léopold Hertz 준영

1
-v opcja w grep wyklucza wynik, to tak, jakby wziąć wszystko oprócz Tux.png
— Rohail Abbas

1
Jest to z pewnością intuicyjne, ale powyższe odpowiedzi są lepsze. Jeśli na przykład piszesz skrypt, wymagałoby to umieszczenia we właściwym katalogu ..
— nJGL

@nJGL Możemy również podać tutaj absolutną ścieżkę, użyłem
— katalogu głównego

@RohailAbbas W porządku. ✌️
— nJGL

14

Dla bash, sth odpowiedź jest poprawna. Oto składnia zsh (moja wybrana powłoka):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Wymaga ustawienia EXTENDED_GLOBopcji powłoki.


3
A co, jeśli chcemy wykluczyć dwa pliki?
— mpen

13

Uważam, że jest to nieco bezpieczniejsze i łatwiejsze do oparcia w przypadku prostych ruchów, które wykluczają określone pliki lub katalogi.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

To najlepsze rozwiązanie dla Busybox / ASH
— Stuart Cardall

1
To zadziałało dla mnie w sytuacji, gdy musiałem przenieść wszystkie pliki oprócz kilku folderów do innego katalogu
— Umar Hayat

-lOpcja lsbędzie zawierać wiele nieistotnych informacji w linii poleceń i spowodować niepowodzenie polecenia mv.
— jdhao

5

Poniższa metoda nie jest metodą gwarantowaną w 100% i nie należy jej w ogóle podejmować w przypadku skryptów. Ale czasami wystarczy do szybkiego użycia powłoki interaktywnej. Plik glob, taki jak

[abc]*

(który dopasuje wszystkie pliki o nazwach zaczynających się od a, b lub c) można zanegować, wstawiając najpierw znak „^”, tj.

[^abc]*

Czasami używam tego, aby nie dopasować katalogu „lost + found”, na przykład:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Oczywiście, jeśli są inne pliki zaczynające się od l, muszę je później przetworzyć.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

Polecenie find wyświetla listę wszystkich zwykłych plików, a polecenie fgrep odfiltrowuje wszystkie pliki Tux.png. Backticks mówią mv, aby przenieść wynikową listę plików.


4
Nigdy, przenigdy nie oceniaj find jako argumentów dla innego polecenia. Zdarzą się złe rzeczy. Być może właśnie stworzyłeś lukę. Zawsze używaj polecenia find -print0 | xargs -0 konstrukcja lub znajdź -exec.
— Juliano

3

Co powiesz na przeniesienie wszystkiego w folderze, a następnie przeniesienie pliku Tux.png z powrotem?

Nie przychodzi mi do głowy żadna składnia powłoki, która mogłaby powiedzieć „wszystko oprócz…” od ręki.


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Wydaje się, że w tym poleceniu brakuje jednej części i nie działa na moim komputerze. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/zamiast tego działa.
— Katherine Chen

3

Co powiesz na:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Musisz jednak być w folderze.


3

Można pominąć grep w ten sposób:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

To mogłoby być prostsze i łatwe do zapamiętania i działa dla mnie.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.